Annotation of prex/usr/server/fs/fatfs/fatfs_vnops.c, Revision 1.1
1.1 ! nbrk 1: /*
! 2: * Copyright (c) 2005-2008, Kohsuke Ohtani
! 3: * All rights reserved.
! 4: *
! 5: * Redistribution and use in source and binary forms, with or without
! 6: * modification, are permitted provided that the following conditions
! 7: * are met:
! 8: * 1. Redistributions of source code must retain the above copyright
! 9: * notice, this list of conditions and the following disclaimer.
! 10: * 2. Redistributions in binary form must reproduce the above copyright
! 11: * notice, this list of conditions and the following disclaimer in the
! 12: * documentation and/or other materials provided with the distribution.
! 13: * 3. Neither the name of the author nor the names of any co-contributors
! 14: * may be used to endorse or promote products derived from this software
! 15: * without specific prior written permission.
! 16: *
! 17: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
! 18: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 19: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 20: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
! 21: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 22: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 23: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 24: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 25: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 26: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 27: * SUCH DAMAGE.
! 28: */
! 29:
! 30: #include <prex/prex.h>
! 31:
! 32: #include <sys/vnode.h>
! 33: #include <sys/file.h>
! 34: #include <sys/mount.h>
! 35: #include <sys/dirent.h>
! 36: #include <sys/buf.h>
! 37:
! 38: #include <ctype.h>
! 39: #include <unistd.h>
! 40: #include <errno.h>
! 41: #include <string.h>
! 42: #include <stdlib.h>
! 43: #include <fcntl.h>
! 44:
! 45: #include "fatfs.h"
! 46:
! 47: /*
! 48: * Time bits: 15-11 hours (0-23), 10-5 min, 4-0 sec /2
! 49: * Date bits: 15-9 year - 1980, 8-5 month, 4-0 day
! 50: */
! 51: #define TEMP_DATE 0x3021
! 52: #define TEMP_TIME 0
! 53:
! 54: #define fatfs_open ((vnop_open_t)vop_nullop)
! 55: #define fatfs_close ((vnop_close_t)vop_nullop)
! 56: static int fatfs_read (vnode_t, file_t, void *, size_t, size_t *);
! 57: static int fatfs_write (vnode_t, file_t, void *, size_t, size_t *);
! 58: #define fatfs_seek ((vnop_seek_t)vop_nullop)
! 59: #define fatfs_ioctl ((vnop_ioctl_t)vop_einval)
! 60: #define fatfs_fsync ((vnop_fsync_t)vop_nullop)
! 61: static int fatfs_readdir(vnode_t, file_t, struct dirent *);
! 62: static int fatfs_lookup (vnode_t, char *, vnode_t);
! 63: static int fatfs_create (vnode_t, char *, mode_t);
! 64: static int fatfs_remove (vnode_t, vnode_t, char *);
! 65: static int fatfs_rename (vnode_t, vnode_t, char *, vnode_t, vnode_t, char *);
! 66: static int fatfs_mkdir (vnode_t, char *, mode_t);
! 67: static int fatfs_rmdir (vnode_t, vnode_t, char *);
! 68: static int fatfs_getattr(vnode_t, struct vattr *);
! 69: static int fatfs_setattr(vnode_t, struct vattr *);
! 70: static int fatfs_inactive(vnode_t);
! 71: static int fatfs_truncate(vnode_t);
! 72:
! 73: /*
! 74: * vnode operations
! 75: */
! 76: struct vnops fatfs_vnops = {
! 77: fatfs_open, /* open */
! 78: fatfs_close, /* close */
! 79: fatfs_read, /* read */
! 80: fatfs_write, /* write */
! 81: fatfs_seek, /* seek */
! 82: fatfs_ioctl, /* ioctl */
! 83: fatfs_fsync, /* fsync */
! 84: fatfs_readdir, /* readdir */
! 85: fatfs_lookup, /* lookup */
! 86: fatfs_create, /* create */
! 87: fatfs_remove, /* remove */
! 88: fatfs_rename, /* remame */
! 89: fatfs_mkdir, /* mkdir */
! 90: fatfs_rmdir, /* rmdir */
! 91: fatfs_getattr, /* getattr */
! 92: fatfs_setattr, /* setattr */
! 93: fatfs_inactive, /* inactive */
! 94: fatfs_truncate, /* truncate */
! 95: };
! 96:
! 97: /*
! 98: * Read one cluster to buffer.
! 99: */
! 100: static int
! 101: fat_read_cluster(struct fatfsmount *fmp, u_long cluster)
! 102: {
! 103: u_long sec;
! 104: size_t size;
! 105:
! 106: sec = cl_to_sec(fmp, cluster);
! 107: size = fmp->sec_per_cl * SEC_SIZE;
! 108: return device_read(fmp->dev, fmp->io_buf, &size, sec);
! 109: }
! 110:
! 111: /*
! 112: * Write one cluster from buffer.
! 113: */
! 114: static int
! 115: fat_write_cluster(struct fatfsmount *fmp, u_long cluster)
! 116: {
! 117: u_long sec;
! 118: size_t size;
! 119:
! 120: sec = cl_to_sec(fmp, cluster);
! 121: size = fmp->sec_per_cl * SEC_SIZE;
! 122: return device_write(fmp->dev, fmp->io_buf, &size, sec);
! 123: }
! 124:
! 125: /*
! 126: * Lookup vnode for the specified file/directory.
! 127: * The vnode data will be set properly.
! 128: */
! 129: static int
! 130: fatfs_lookup(vnode_t dvp, char *name, vnode_t vp)
! 131: {
! 132: struct fatfsmount *fmp;
! 133: struct fat_dirent *de;
! 134: struct fatfs_node *np;
! 135: int err;
! 136:
! 137: if (*name == '\0')
! 138: return ENOENT;
! 139:
! 140: fmp = vp->v_mount->m_data;
! 141: mutex_lock(&fmp->lock);
! 142:
! 143: DPRINTF(("fatfs_lookup: name=%s\n", name));
! 144:
! 145: np = vp->v_data;
! 146: err = fatfs_lookup_node(dvp, name, np);
! 147: if (err) {
! 148: DPRINTF(("fatfs_lookup: failed!! name=%s\n", name));
! 149: mutex_unlock(&fmp->lock);
! 150: return err;
! 151: }
! 152: de = &np->dirent;
! 153: vp->v_type = IS_DIR(de) ? VDIR : VREG;
! 154: fat_attr_to_mode(de->attr, &vp->v_mode);
! 155: vp->v_mode = ALLPERMS;
! 156: vp->v_size = de->size;
! 157: vp->v_blkno = de->cluster;
! 158:
! 159: DPRINTF(("fatfs_lookup: cl=%d\n", de->cluster));
! 160: mutex_unlock(&fmp->lock);
! 161: return 0;
! 162: }
! 163:
! 164: static int
! 165: fatfs_read(vnode_t vp, file_t fp, void *buf, size_t size, size_t *result)
! 166: {
! 167: struct fatfsmount *fmp;
! 168: int nr_read, nr_copy, buf_pos, err;
! 169: u_long cl, file_pos;
! 170:
! 171: DPRINTF(("fatfs_read: vp=%x\n", vp));
! 172:
! 173: *result = 0;
! 174: fmp = vp->v_mount->m_data;
! 175:
! 176: if (vp->v_type == VDIR)
! 177: return EISDIR;
! 178: if (vp->v_type != VREG)
! 179: return EINVAL;
! 180:
! 181: /* Check if current file position is already end of file. */
! 182: file_pos = fp->f_offset;
! 183: if (file_pos >= vp->v_size)
! 184: return 0;
! 185:
! 186: mutex_lock(&fmp->lock);
! 187:
! 188: /* Get the actual read size. */
! 189: if (vp->v_size - file_pos < size)
! 190: size = vp->v_size - file_pos;
! 191:
! 192: /* Seek to the cluster for the file offset */
! 193: err = fat_seek_cluster(fmp, vp->v_blkno, file_pos, &cl);
! 194: if (err)
! 195: goto out;
! 196:
! 197: /* Read and copy data */
! 198: nr_read = 0;
! 199: buf_pos = file_pos % fmp->cluster_size;
! 200: do {
! 201: if (fat_read_cluster(fmp, cl)) {
! 202: err = EIO;
! 203: goto out;
! 204: }
! 205:
! 206: nr_copy = fmp->cluster_size;
! 207: if (buf_pos > 0)
! 208: nr_copy -= buf_pos;
! 209: if (buf_pos + size < fmp->cluster_size)
! 210: nr_copy = size;
! 211: memcpy(buf, fmp->io_buf + buf_pos, nr_copy);
! 212:
! 213: file_pos += nr_copy;
! 214: nr_read += nr_copy;
! 215: size -= nr_copy;
! 216: if (size <= 0)
! 217: break;
! 218:
! 219: err = fat_next_cluster(fmp, cl, &cl);
! 220: if (err)
! 221: goto out;
! 222:
! 223: buf = (void *)((u_long)buf + nr_copy);
! 224: buf_pos = 0;
! 225: } while (!IS_EOFCL(fmp, cl));
! 226:
! 227: fp->f_offset = file_pos;
! 228: *result = nr_read;
! 229: err = 0;
! 230: out:
! 231: mutex_unlock(&fmp->lock);
! 232: return err;
! 233: }
! 234:
! 235: static int
! 236: fatfs_write(vnode_t vp, file_t fp, void *buf, size_t size, size_t *result)
! 237: {
! 238: struct fatfsmount *fmp;
! 239: struct fatfs_node *np;
! 240: struct fat_dirent *de;
! 241: int nr_copy, nr_write, buf_pos, i, cl_size, err;
! 242: u_long file_pos, end_pos;
! 243: u_long cl;
! 244:
! 245: DPRINTF(("fatfs_write: vp=%x\n", vp));
! 246:
! 247: *result = 0;
! 248: fmp = vp->v_mount->m_data;
! 249:
! 250: if (vp->v_type == VDIR)
! 251: return EISDIR;
! 252: if (vp->v_type != VREG)
! 253: return EINVAL;
! 254:
! 255: mutex_lock(&fmp->lock);
! 256:
! 257: /* Check if file position exceeds the end of file. */
! 258: end_pos = vp->v_size;
! 259: file_pos = (fp->f_flags & O_APPEND) ? end_pos : fp->f_offset;
! 260: if (file_pos + size > end_pos) {
! 261: /* Expand the file size before writing to it */
! 262: end_pos = file_pos + size;
! 263: err = fat_expand_file(fmp, vp->v_blkno, end_pos);
! 264: if (err) {
! 265: err = EIO;
! 266: goto out;
! 267: }
! 268:
! 269: /* Update directory entry */
! 270: np = vp->v_data;
! 271: de = &np->dirent;
! 272: de->size = end_pos;
! 273: err = fatfs_put_node(fmp, np);
! 274: if (err)
! 275: goto out;
! 276: vp->v_size = end_pos;
! 277: }
! 278:
! 279: /* Seek to the cluster for the file offset */
! 280: err = fat_seek_cluster(fmp, vp->v_blkno, file_pos, &cl);
! 281: if (err)
! 282: goto out;
! 283:
! 284: buf_pos = file_pos % fmp->cluster_size;
! 285: cl_size = size / fmp->cluster_size + 1;
! 286: nr_write = 0;
! 287: i = 0;
! 288: do {
! 289: /* First and last cluster must be read before write */
! 290: if (i == 0 || i == cl_size) {
! 291: if (fat_read_cluster(fmp, cl)) {
! 292: err = EIO;
! 293: goto out;
! 294: }
! 295: }
! 296: nr_copy = fmp->cluster_size;
! 297: if (buf_pos > 0)
! 298: nr_copy -= buf_pos;
! 299: if (buf_pos + size < fmp->cluster_size)
! 300: nr_copy = size;
! 301: memcpy(fmp->io_buf + buf_pos, buf, nr_copy);
! 302:
! 303: if (fat_write_cluster(fmp, cl)) {
! 304: err = EIO;
! 305: goto out;
! 306: }
! 307: file_pos += nr_copy;
! 308: nr_write += nr_copy;
! 309: size -= nr_copy;
! 310: if (size <= 0)
! 311: break;
! 312:
! 313: err = fat_next_cluster(fmp, cl, &cl);
! 314: if (err)
! 315: goto out;
! 316:
! 317: buf = (void *)((u_long)buf + nr_copy);
! 318: buf_pos = 0;
! 319: i++;
! 320: } while (!IS_EOFCL(fmp, cl));
! 321:
! 322: fp->f_offset = file_pos;
! 323:
! 324: /*
! 325: * XXX: Todo!
! 326: * de.time = ?
! 327: * de.date = ?
! 328: * if (dirent_set(fp, &de))
! 329: * return EIO;
! 330: */
! 331: *result = nr_write;
! 332: err = 0;
! 333: out:
! 334: mutex_unlock(&fmp->lock);
! 335: return err;
! 336: }
! 337:
! 338: static int
! 339: fatfs_readdir(vnode_t vp, file_t fp, struct dirent *dir)
! 340: {
! 341: struct fatfsmount *fmp;
! 342: struct fatfs_node np;
! 343: struct fat_dirent *de;
! 344: int err;
! 345:
! 346: fmp = vp->v_mount->m_data;
! 347: mutex_lock(&fmp->lock);
! 348:
! 349: err = fatfs_get_node(vp, fp->f_offset, &np);
! 350: if (err)
! 351: goto out;
! 352: de = &np.dirent;
! 353: fat_restore_name((char *)&de->name, dir->d_name);
! 354:
! 355: if (de->attr & FA_SUBDIR)
! 356: dir->d_type = DT_DIR;
! 357: else if (de->attr & FA_DEVICE)
! 358: dir->d_type = DT_BLK;
! 359: else
! 360: dir->d_type = DT_REG;
! 361:
! 362: dir->d_fileno = fp->f_offset;
! 363: dir->d_namlen = strlen(dir->d_name);
! 364:
! 365: fp->f_offset++;
! 366: err = 0;
! 367: out:
! 368: mutex_unlock(&fmp->lock);
! 369: return err;
! 370: }
! 371:
! 372: /*
! 373: * Create empty file.
! 374: */
! 375: static int
! 376: fatfs_create(vnode_t dvp, char *name, mode_t mode)
! 377: {
! 378: struct fatfsmount *fmp;
! 379: struct fatfs_node np;
! 380: struct fat_dirent *de;
! 381: u_long cl;
! 382: int err;
! 383:
! 384: DPRINTF(("fatfs_create: %s\n", name));
! 385:
! 386: if (!S_ISREG(mode))
! 387: return EINVAL;
! 388:
! 389: if (!fat_valid_name(name))
! 390: return EINVAL;
! 391:
! 392: fmp = dvp->v_mount->m_data;
! 393: mutex_lock(&fmp->lock);
! 394:
! 395: /* Allocate free cluster for new file. */
! 396: err = fat_alloc_cluster(fmp, 0, &cl);
! 397: if (err)
! 398: goto out;
! 399:
! 400: de = &np.dirent;
! 401: memset(de, 0, sizeof(struct fat_dirent));
! 402: fat_convert_name(name, (char *)de->name);
! 403: de->cluster = cl;
! 404: de->time = TEMP_TIME;
! 405: de->date = TEMP_DATE;
! 406: fat_mode_to_attr(mode, &de->attr);
! 407: err = fatfs_add_node(dvp, &np);
! 408: if (err)
! 409: goto out;
! 410: err = fat_set_cluster(fmp, cl, fmp->fat_eof);
! 411: out:
! 412: mutex_unlock(&fmp->lock);
! 413: return err;
! 414: }
! 415:
! 416: static int
! 417: fatfs_remove(vnode_t dvp, vnode_t vp, char *name)
! 418: {
! 419: struct fatfsmount *fmp;
! 420: struct fatfs_node np;
! 421: struct fat_dirent *de;
! 422: int err;
! 423:
! 424: if (*name == '\0')
! 425: return ENOENT;
! 426:
! 427: fmp = dvp->v_mount->m_data;
! 428: mutex_lock(&fmp->lock);
! 429:
! 430: err = fatfs_lookup_node(dvp, name, &np);
! 431: if (err)
! 432: goto out;
! 433: de = &np.dirent;
! 434: if (IS_DIR(de)) {
! 435: err = EISDIR;
! 436: goto out;
! 437: }
! 438: if (!IS_FILE(de)) {
! 439: err = EPERM;
! 440: goto out;
! 441: }
! 442:
! 443: /* Remove clusters */
! 444: err = fat_free_clusters(fmp, de->cluster);
! 445: if (err)
! 446: goto out;
! 447:
! 448: /* remove directory */
! 449: de->name[0] = 0xe5;
! 450: err = fatfs_put_node(fmp, &np);
! 451: out:
! 452: mutex_unlock(&fmp->lock);
! 453: return err;
! 454: }
! 455:
! 456: static int
! 457: fatfs_rename(vnode_t dvp1, vnode_t vp1, char *name1,
! 458: vnode_t dvp2, vnode_t vp2, char *name2)
! 459: {
! 460: struct fatfsmount *fmp;
! 461: struct fatfs_node np1;
! 462: struct fat_dirent *de1, *de2;
! 463: int err;
! 464:
! 465: fmp = dvp1->v_mount->m_data;
! 466: mutex_lock(&fmp->lock);
! 467:
! 468: err = fatfs_lookup_node(dvp1, name1, &np1);
! 469: if (err)
! 470: goto out;
! 471: de1 = &np1.dirent;
! 472:
! 473: if (IS_FILE(de1)) {
! 474: /* Remove destination file, first */
! 475: err = fatfs_remove(dvp2, vp1, name2);
! 476: if (err == EIO)
! 477: goto out;
! 478:
! 479: /* Change file name of directory entry */
! 480: fat_convert_name(name2, (char *)de1->name);
! 481:
! 482: /* Same directory ? */
! 483: if (dvp1 == dvp2) {
! 484: /* Change the name of existing file */
! 485: err = fatfs_put_node(fmp, &np1);
! 486: if (err)
! 487: goto out;
! 488: } else {
! 489: /* Create new directory entry */
! 490: err = fatfs_add_node(dvp2, &np1);
! 491: if (err)
! 492: goto out;
! 493:
! 494: /* Remove souce file */
! 495: err = fatfs_remove(dvp1, vp2, name1);
! 496: if (err)
! 497: goto out;
! 498: }
! 499: } else {
! 500:
! 501: /* remove destination directory */
! 502: err = fatfs_rmdir(dvp2, NULL, name2);
! 503: if (err == EIO)
! 504: goto out;
! 505:
! 506: /* Change file name of directory entry */
! 507: fat_convert_name(name2, (char *)de1->name);
! 508:
! 509: /* Same directory ? */
! 510: if (dvp1 == dvp2) {
! 511: /* Change the name of existing directory */
! 512: err = fatfs_put_node(fmp, &np1);
! 513: if (err)
! 514: goto out;
! 515: } else {
! 516: /* Create new directory entry */
! 517: err = fatfs_add_node(dvp2, &np1);
! 518: if (err)
! 519: goto out;
! 520:
! 521: /* Update "." and ".." for renamed directory */
! 522: if (fat_read_cluster(fmp, de1->cluster)) {
! 523: err = EIO;
! 524: goto out;
! 525: }
! 526:
! 527: de2 = (struct fat_dirent *)fmp->io_buf;
! 528: de2->cluster = de1->cluster;
! 529: de2->time = TEMP_TIME;
! 530: de2->date = TEMP_DATE;
! 531: de2++;
! 532: de2->cluster = dvp2->v_blkno;
! 533: de2->time = TEMP_TIME;
! 534: de2->date = TEMP_DATE;
! 535:
! 536: if (fat_write_cluster(fmp, de1->cluster)) {
! 537: err = EIO;
! 538: goto out;
! 539: }
! 540:
! 541: /* Remove souce directory */
! 542: err = fatfs_rmdir(dvp1, NULL, name1);
! 543: if (err)
! 544: goto out;
! 545: }
! 546: }
! 547: out:
! 548: mutex_unlock(&fmp->lock);
! 549: return err;
! 550: }
! 551:
! 552: static int
! 553: fatfs_mkdir(vnode_t dvp, char *name, mode_t mode)
! 554: {
! 555: struct fatfsmount *fmp;
! 556: struct fatfs_node np;
! 557: struct fat_dirent *de;
! 558: u_long cl;
! 559: int err;
! 560:
! 561: if (!S_ISDIR(mode))
! 562: return EINVAL;
! 563:
! 564: if (!fat_valid_name(name))
! 565: return ENOTDIR;
! 566:
! 567: fmp = dvp->v_mount->m_data;
! 568: mutex_lock(&fmp->lock);
! 569:
! 570: /* Allocate free cluster for directory data */
! 571: err = fat_alloc_cluster(fmp, 0, &cl);
! 572: if (err)
! 573: goto out;
! 574:
! 575: memset(&np, 0, sizeof(struct fatfs_node));
! 576: de = &np.dirent;
! 577: fat_convert_name(name, (char *)&de->name);
! 578: de->cluster = cl;
! 579: de->time = TEMP_TIME;
! 580: de->date = TEMP_DATE;
! 581: fat_mode_to_attr(mode, &de->attr);
! 582: err = fatfs_add_node(dvp, &np);
! 583: if (err)
! 584: goto out;
! 585:
! 586: /* Initialize "." and ".." for new directory */
! 587: memset(fmp->io_buf, 0, fmp->cluster_size);
! 588:
! 589: de = (struct fat_dirent *)fmp->io_buf;
! 590: memcpy(de->name, ". ", 11);
! 591: de->attr = FA_SUBDIR;
! 592: de->cluster = cl;
! 593: de->time = TEMP_TIME;
! 594: de->date = TEMP_DATE;
! 595: de++;
! 596: memcpy(de->name, ".. ", 11);
! 597: de->attr = FA_SUBDIR;
! 598: de->cluster = dvp->v_blkno;
! 599: de->time = TEMP_TIME;
! 600: de->date = TEMP_DATE;
! 601:
! 602: if (fat_write_cluster(fmp, cl)) {
! 603: err = EIO;
! 604: goto out;
! 605: }
! 606: /* Add eof */
! 607: err = fat_set_cluster(fmp, cl, fmp->fat_eof);
! 608: out:
! 609: mutex_unlock(&fmp->lock);
! 610: return err;
! 611: }
! 612:
! 613: /*
! 614: * remove can be done only with empty directory
! 615: */
! 616: static int
! 617: fatfs_rmdir(vnode_t dvp, vnode_t vp, char *name)
! 618: {
! 619: struct fatfsmount *fmp;
! 620: struct fatfs_node np;
! 621: struct fat_dirent *de;
! 622: int err;
! 623:
! 624: if (*name == '\0')
! 625: return ENOENT;
! 626:
! 627: fmp = dvp->v_mount->m_data;
! 628: mutex_lock(&fmp->lock);
! 629:
! 630: err = fatfs_lookup_node(dvp, name, &np);
! 631: if (err)
! 632: goto out;
! 633:
! 634: de = &np.dirent;
! 635: if (!IS_DIR(de)) {
! 636: err = ENOTDIR;
! 637: goto out;
! 638: }
! 639:
! 640: /* Remove clusters */
! 641: err = fat_free_clusters(fmp, de->cluster);
! 642: if (err)
! 643: goto out;
! 644:
! 645: /* remove directory */
! 646: de->name[0] = 0xe5;
! 647:
! 648: err = fatfs_put_node(fmp, &np);
! 649: out:
! 650: mutex_unlock(&fmp->lock);
! 651: return err;
! 652: }
! 653:
! 654: static int
! 655: fatfs_getattr(vnode_t vp, struct vattr *vap)
! 656: {
! 657: /* XXX */
! 658: return 0;
! 659: }
! 660:
! 661: static int
! 662: fatfs_setattr(vnode_t vp, struct vattr *vap)
! 663: {
! 664: /* XXX */
! 665: return 0;
! 666: }
! 667:
! 668:
! 669: static int
! 670: fatfs_inactive(vnode_t vp)
! 671: {
! 672:
! 673: free(vp->v_data);
! 674: return 0;
! 675: }
! 676:
! 677: static int
! 678: fatfs_truncate(vnode_t vp)
! 679: {
! 680: struct fatfsmount *fmp;
! 681: struct fatfs_node *np;
! 682: struct fat_dirent *de;
! 683: int err;
! 684:
! 685: fmp = vp->v_mount->m_data;
! 686: mutex_lock(&fmp->lock);
! 687:
! 688: np = vp->v_data;
! 689: de = &np->dirent;
! 690:
! 691: /* Remove clusters */
! 692: err = fat_free_clusters(fmp, de->cluster);
! 693: if (err)
! 694: goto out;
! 695:
! 696: de->size = 0;
! 697:
! 698: err = fatfs_put_node(fmp, np);
! 699: if (err)
! 700: goto out;
! 701:
! 702: vp->v_size = 0;
! 703: out:
! 704: mutex_unlock(&fmp->lock);
! 705: return err;
! 706: }
! 707:
! 708: int
! 709: fatfs_init(void)
! 710: {
! 711: return 0;
! 712: }
CVSweb