int link(char *oldname, char *newname) { struct fs *oldfs; struct fs *newfs; char *oldrest; char *newrest; int rc; char oldpath[MAXPATH]; char newpath[MAXPATH]; rc = canonicalize(oldname, oldpath); if (rc < 0) return rc; rc = fslookup(oldpath, 0, &oldfs, &oldrest); if (rc < 0) return rc; rc = canonicalize(newname, newpath); if (rc < 0) return rc; rc = fslookup(newpath, 0, &newfs, &newrest); if (rc < 0) return rc; if (oldfs != newfs) return -EXDEV; if (!oldfs->ops->link) return -ENOSYS; oldfs->locks++; if (lock_fs(oldfs, FSOP_LINK) < 0) { oldfs->locks--; return -ETIMEOUT; } rc = oldfs->ops->link(oldfs, oldrest, newrest); unlock_fs(oldfs, FSOP_LINK); oldfs->locks--; return rc; }
int utime(char *name, struct utimbuf *times) { struct fs *fs; char *rest; int rc; char path[MAXPATH]; rc = canonicalize(name, path); if (rc < 0) return rc; rc = fslookup(path, 0, &fs, &rest); if (rc < 0) return rc; if (!times) return -EINVAL; if (!fs->ops->utime) return -ENOSYS; fs->locks++; if (lock_fs(fs, FSOP_UTIME) < 0) { fs->locks--; return -ETIMEOUT; } rc = fs->ops->utime(fs, rest, times); unlock_fs(fs, FSOP_UTIME); fs->locks--; return rc; }
int chdir(char *name) { struct fs *fs; char *rest; int rc; char path[MAXPATH]; char newdir[MAXPATH]; struct stat64 buffer; rc = canonicalize(name, path); if (rc < 0) return rc; strcpy(newdir, path); rc = fslookup(path, 0, &fs, &rest); if (rc < 0) return rc; if (fs->ops->stat) { fs->locks++; if (lock_fs(fs, FSOP_STAT) < 0) { fs->locks--; return -ETIMEOUT; } rc = fs->ops->stat(fs, rest, &buffer); unlock_fs(fs, FSOP_STAT); fs->locks--; if (rc < 0) return rc; if ((buffer.st_mode & S_IFMT) != S_IFDIR) return -ENOTDIR; } strcpy(self()->curdir, newdir); return 0; }
static int rlookup(SunMsg *m) { Nfs3TLookup *tx = (Nfs3TLookup*)m->call; Nfs3RLookup rx; SunAuthUnix au; int ok; if((ok = authunixunpack(&m->rpc, &au)) != SunSuccess) return sunmsgreplyerror(m, ok); memset(&rx, 0, sizeof rx); rx.status = fsgetattr(&au, &tx->handle, &rx.dirAttr); if(rx.status != Nfs3Ok) return sunmsgreply(m, &rx.call); rx.haveDirAttr = 1; rx.status = fslookup(&au, &tx->handle, tx->name, &rx.handle); if(rx.status != Nfs3Ok) return sunmsgreply(m, &rx.call); rx.status = fsgetattr(&au, &rx.handle, &rx.attr); if(rx.status != Nfs3Ok) return sunmsgreply(m, &rx.call); rx.haveAttr = 1; return sunmsgreply(m, &rx.call); }
int open(char *name, int flags, int mode, struct file **retval) { struct fs *fs; struct file *filp; int rc; char *rest; char path[MAXPATH]; rc = canonicalize(name, path); if (rc < 0) return rc; rc = fslookup(path, 0, &fs, &rest); if (rc < 0) return rc; filp = newfile(fs, path, flags, mode); if (!filp) return -EMFILE; if (fs->ops->open) { fs->locks++; if (lock_fs(fs, FSOP_OPEN) < 0) { fs->locks--; kfree(filp->path); kfree(filp); return -ETIMEOUT; } rc = fs->ops->open(filp, rest); if (rc == 0) { int access; if (filp->flags & O_RDWR) { access = S_IREAD | S_IWRITE; } else if (filp->flags & O_WRONLY) { access = S_IWRITE; } else { access = S_IREAD; } rc = check(filp->mode, filp->owner, filp->group, access); } unlock_fs(fs, FSOP_OPEN); if (rc != 0) { fs->locks--; kfree(filp->path); kfree(filp); return rc; } } *retval = filp; return 0; }
int statfs(char *name, struct statfs *buf) { struct fs *fs; char *rest; int rc; char path[MAXPATH]; rc = canonicalize(name, path); if (rc < 0) return rc; rc = fslookup(path, 1, &fs, &rest); if (rc < 0) return rc; return get_fsstat(fs, buf); }
int access(char *name, int mode) { struct fs *fs; char *rest; int rc; char path[MAXPATH]; rc = canonicalize(name, path); if (rc < 0) return rc; rc = fslookup(path, 0, &fs, &rest); if (rc < 0) return rc; if (!fs->ops->access) { struct thread *thread = self(); struct stat64 buf; rc = stat(name, &buf); if (rc < 0) return rc; if (mode == 0) return 0; if (thread->euid == 0) { if (mode == X_OK) { return buf.st_mode & 0111 ? 0 : -EACCES; } else { return 0; } } if (thread->euid == buf.st_uid) { mode <<= 6; } else if (thread->egid == buf.st_gid) { mode <<= 3; } if ((mode && buf.st_mode) == 0) return -EACCES; return 0; } fs->locks++; if (lock_fs(fs, FSOP_ACCESS) < 0) { fs->locks--; return -ETIMEOUT; } rc = fs->ops->access(fs, rest, mode); unlock_fs(fs, FSOP_ACCESS); fs->locks--; return rc; }
int opendir(char *name, struct file **retval) { struct fs *fs; struct file *filp; int rc; char *rest; char path[MAXPATH]; rc = canonicalize(name, path); if (rc < 0) return rc; rc = fslookup(path, 1, &fs, &rest); if (rc < 0) return rc; if (!fs->ops->opendir) return -ENOSYS; filp = (struct file *) kmalloc(sizeof(struct file)); if (!filp) return -ENOMEM; init_ioobject(&filp->iob, OBJECT_FILE); filp->fs = fs; filp->flags = O_RDONLY | F_DIR; filp->pos = 0; filp->data = NULL; filp->path = strdup(path); fs->locks++; if (lock_fs(fs, FSOP_OPENDIR) < 0) { fs->locks--; kfree(filp->path); kfree(filp); return -ETIMEOUT; } rc = fs->ops->opendir(filp, rest); unlock_fs(fs, FSOP_OPENDIR); if (rc != 0) { fs->locks--; kfree(filp->path); kfree(filp); return rc; } *retval = filp; return 0; }
int stat(char *name, struct stat64 *buffer) { struct fs *fs; char *rest; int rc; char path[MAXPATH]; rc = canonicalize(name, path); if (rc < 0) return rc; rc = fslookup(path, 0, &fs, &rest); if (rc < 0) return rc; if (!fs->ops->stat) return -ENOSYS; fs->locks++; if (lock_fs(fs, FSOP_STAT) < 0) { fs->locks--; return -ETIMEOUT; } rc = fs->ops->stat(fs, rest, buffer); unlock_fs(fs, FSOP_STAT); fs->locks--; return rc; }
int unlink(char *name) { struct fs *fs; char *rest; int rc; char path[MAXPATH]; rc = canonicalize(name, path); if (rc < 0) return rc; rc = fslookup(path, 0, &fs, &rest); if (rc < 0) return rc; if (!fs->ops->unlink) return -ENOSYS; fs->locks++; if (lock_fs(fs, FSOP_UNLINK) < 0) { fs->locks--; return -ETIMEOUT; } rc = fs->ops->unlink(fs, rest); fs->locks--; unlock_fs(fs, FSOP_UNLINK); return rc; }
int mkdir(char *name, int mode) { struct fs *fs; char *rest; int rc; char path[MAXPATH]; rc = canonicalize(name, path); if (rc < 0) return rc; rc = fslookup(path, 0, &fs, &rest); if (rc < 0) return rc; if (!fs->ops->mkdir) return -ENOSYS; fs->locks++; if (lock_fs(fs, FSOP_MKDIR) < 0) { fs->locks--; return -ETIMEOUT; } rc = fs->ops->mkdir(fs, rest, mode & ~(peb ? peb->umaskval : 0)); unlock_fs(fs, FSOP_MKDIR); fs->locks--; return rc; }
int chown(char *name, int owner, int group) { struct fs *fs; char *rest; int rc; char path[MAXPATH]; rc = canonicalize(name, path); if (rc < 0) return rc; rc = fslookup(path, 0, &fs, &rest); if (rc < 0) return rc; if (!fs->ops->chmod) return -ENOSYS; fs->locks++; if (lock_fs(fs, FSOP_CHOWN) < 0) { fs->locks--; return -ETIMEOUT; } rc = fs->ops->chown(fs, rest, owner, group); unlock_fs(fs, FSOP_CHOWN); fs->locks--; return rc; }