sf_dentry_revalidate(struct dentry *dentry, struct nameidata *nd) #endif { TRACE(); if (sf_inode_revalidate(dentry)) return 0; return 1; }
int sf_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *kstat) { int err; TRACE(); err = sf_inode_revalidate(dentry); if (err) return err; generic_fillattr(dentry->d_inode, kstat); return 0; }
sf_dentry_revalidate(struct dentry *dentry, int flags) #endif { TRACE(); #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) if (flags & LOOKUP_RCU) return -ECHILD; #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38) /* see Documentation/filesystems/vfs.txt */ if (nd && nd->flags & LOOKUP_RCU) return -ECHILD; #endif if (sf_inode_revalidate(dentry)) return 0; return 1; }
int sf_setattr(struct dentry *dentry, struct iattr *iattr) { struct sf_glob_info *sf_g; struct sf_inode_info *sf_i; SHFLCREATEPARMS params; SHFLFSOBJINFO info; uint32_t cbBuffer; int rc, err; TRACE(); sf_g = GET_GLOB_INFO(dentry->d_inode->i_sb); sf_i = GET_INODE_INFO(dentry->d_inode); err = 0; RT_ZERO(params); params.Handle = SHFL_HANDLE_NIL; params.CreateFlags = SHFL_CF_ACT_OPEN_IF_EXISTS | SHFL_CF_ACT_FAIL_IF_NEW | SHFL_CF_ACCESS_ATTR_WRITE; /* this is at least required for Posix hosts */ if (iattr->ia_valid & ATTR_SIZE) params.CreateFlags |= SHFL_CF_ACCESS_WRITE; rc = VbglR0SfCreate(&client_handle, &sf_g->map, sf_i->path, ¶ms); if (RT_FAILURE(rc)) { LogFunc(("VbglR0SfCreate(%s) failed rc=%Rrc\n", sf_i->path->String.utf8, rc)); err = -RTErrConvertToErrno(rc); goto fail2; } if (params.Result != SHFL_FILE_EXISTS) { LogFunc(("file %s does not exist\n", sf_i->path->String.utf8)); err = -ENOENT; goto fail1; } /* Setting the file size and setting the other attributes has to be * handled separately, see implementation of vbsfSetFSInfo() in * vbsf.cpp */ if (iattr->ia_valid & (ATTR_MODE | ATTR_ATIME | ATTR_MTIME)) { #define mode_set(r) ((iattr->ia_mode & (S_##r)) ? RTFS_UNIX_##r : 0) RT_ZERO(info); if (iattr->ia_valid & ATTR_MODE) { info.Attr.fMode = mode_set(ISUID); info.Attr.fMode |= mode_set(ISGID); info.Attr.fMode |= mode_set(IRUSR); info.Attr.fMode |= mode_set(IWUSR); info.Attr.fMode |= mode_set(IXUSR); info.Attr.fMode |= mode_set(IRGRP); info.Attr.fMode |= mode_set(IWGRP); info.Attr.fMode |= mode_set(IXGRP); info.Attr.fMode |= mode_set(IROTH); info.Attr.fMode |= mode_set(IWOTH); info.Attr.fMode |= mode_set(IXOTH); if (iattr->ia_mode & S_IFDIR) info.Attr.fMode |= RTFS_TYPE_DIRECTORY; else info.Attr.fMode |= RTFS_TYPE_FILE; } if (iattr->ia_valid & ATTR_ATIME) sf_timespec_from_ftime(&info.AccessTime, &iattr->ia_atime); if (iattr->ia_valid & ATTR_MTIME) sf_timespec_from_ftime(&info.ModificationTime, &iattr->ia_mtime); /* ignore ctime (inode change time) as it can't be set from userland anyway */ cbBuffer = sizeof(info); rc = VbglR0SfFsInfo(&client_handle, &sf_g->map, params.Handle, SHFL_INFO_SET | SHFL_INFO_FILE, &cbBuffer, (PSHFLDIRINFO)&info); if (RT_FAILURE(rc)) { LogFunc(("VbglR0SfFsInfo(%s, FILE) failed rc=%Rrc\n", sf_i->path->String.utf8, rc)); err = -RTErrConvertToErrno(rc); goto fail1; } } if (iattr->ia_valid & ATTR_SIZE) { RT_ZERO(info); info.cbObject = iattr->ia_size; cbBuffer = sizeof(info); rc = VbglR0SfFsInfo(&client_handle, &sf_g->map, params.Handle, SHFL_INFO_SET | SHFL_INFO_SIZE, &cbBuffer, (PSHFLDIRINFO)&info); if (RT_FAILURE(rc)) { LogFunc(("VbglR0SfFsInfo(%s, SIZE) failed rc=%Rrc\n", sf_i->path->String.utf8, rc)); err = -RTErrConvertToErrno(rc); goto fail1; } } rc = VbglR0SfClose(&client_handle, &sf_g->map, params.Handle); if (RT_FAILURE(rc)) LogFunc(("VbglR0SfClose(%s) failed rc=%Rrc\n", sf_i->path->String.utf8, rc)); return sf_inode_revalidate(dentry); fail1: rc = VbglR0SfClose(&client_handle, &sf_g->map, params.Handle); if (RT_FAILURE(rc)) LogFunc(("VbglR0SfClose(%s) failed rc=%Rrc\n", sf_i->path->String.utf8, rc)); fail2: return err; }