/* Makes an absolute path from nameidata, and allocates a string for it */ static char* absolutePath(struct dentry *dentry, struct vfsmount *mnt) { char* path; size_t path_size = 0; char* absolute = NULL; ISystemRoot* root; char* apath; path = talpa_alloc_path(&path_size); if ( !path ) { return NULL; } root = TALPA_Portability()->systemRoot(); apath = talpa__d_path(dentry, mnt, root->directoryEntry(root->object), root->mountPoint(root->object), path, path_size); if (unlikely( apath == NULL )) { bool isDeleted = false; if ( dentry ) { isDeleted = (!IS_ROOT(dentry) && d_unhashed(dentry)); } critical("talpa__d_path failed for mnt=0x%p fstype=%s, dentry=0x%p deleted=%d", mnt, (const char *)mnt->mnt_sb->s_type->name, dentry, isDeleted); } else if (unlikely (IS_ERR(apath))) { apath = NULL; } else { absolute = talpa_alloc(strlen(apath) + 1); if ( absolute ) { strcpy(absolute, apath); } } talpa_free_path(path); return absolute; }
char* talpa__d_namespace_path( struct dentry *dentry, struct vfsmount *vfsmnt, struct dentry *root, struct vfsmount *rootmnt, char *buffer, int buflen, bool* nonRootNamespaceOut, bool* inProcessNamespaceOut) { char* path; #ifdef TALPA_MNT_NAMESPACE struct vfsmount *ns_root_mnt = NULL; struct dentry *ns_root_dentry; unsigned m_seq = 1; struct vfsmount *process_root_mnt; struct dentry *process_root_dentry; struct task_struct* proc; proc = current; if ( likely(proc->fs != NULL) ) { talpa_proc_fs_lock(&proc->fs->lock); process_root_mnt = mntget(talpa_task_root_mnt(proc)); process_root_dentry = dget(talpa_task_root_dentry(proc)); talpa_proc_fs_unlock(&proc->fs->lock); if (inProcessNamespaceOut) { if ( likely( proc->nsproxy != NULL ) ) { *inProcessNamespaceOut = (getNamespaceInfo(vfsmnt) == proc->nsproxy->mnt_ns); } else { *inProcessNamespaceOut = false; } } talpa_vfsmount_lock(&m_seq); if (getNamespaceInfo(process_root_mnt)) { ns_root_mnt = mntget(getNamespaceRoot(process_root_mnt)); } talpa_vfsmount_unlock(&m_seq); dbg("root dentry %s dentry=%p vfsmnt=%p",process_root_dentry->d_name.name,process_root_dentry,process_root_mnt); if(ns_root_mnt) { ns_root_dentry = dget(ns_root_mnt->mnt_root); dbg("ns_root_dentry %s dentry=%p vfsmnt=%p",ns_root_dentry->d_name.name,ns_root_dentry,ns_root_mnt); path = talpa__d_path(dentry, vfsmnt, ns_root_dentry, ns_root_mnt, buffer, buflen, NULL); dbg("talpa__d_namespace_path: found d_namespace_path: %s", path); if (nonRootNamespaceOut) { *nonRootNamespaceOut = (ns_root_mnt != rootmnt); } dput(ns_root_dentry); mntput(ns_root_mnt); } else { path = talpa__d_path(dentry, vfsmnt, process_root_dentry, process_root_mnt, buffer, buflen, nonRootNamespaceOut); dbg("talpa__d_namespace_path: found non namespace path: %s", path); } dput(process_root_dentry); mntput(process_root_mnt); } else { dbg("proc->fs == NULL, cannot get namespace path"); if (inProcessNamespaceOut) { *inProcessNamespaceOut = false; } #else /* !TALPA_MNT_NAMESPACE */ { if (inProcessNamespaceOut) { *inProcessNamespaceOut = true; } #endif path = talpa__d_path(dentry, vfsmnt, root, rootmnt, buffer, buflen, nonRootNamespaceOut); dbg("talpa__d_namespace_path: found non namespace path: %s", path); } return path; } #ifdef TALPA_MNT_NAMESPACE static void debugPathWalk( struct dentry *dentry, struct vfsmount *vfsmnt, struct dentry *root, struct vfsmount *rootmnt) { /* Debug - try and evaluate roots */ int count = 50; struct dentry *td = dentry; struct vfsmount *temp_vfsmnt = vfsmnt; err("DEBUG: expected root node %s dentry=%p vfsmnt=%p",root->d_name.name,root,rootmnt); while (td != root || temp_vfsmnt != rootmnt) { count--; if (count == 0) { err("DEBUG: reached count limit!"); break; } err("DEBUG: examining %s %p",td->d_name.name,td); if (td == temp_vfsmnt->mnt_root || IS_ROOT(td)) { struct vfsmount *temp2_vfsmnt = getParent(temp_vfsmnt); if (td == temp_vfsmnt->mnt_root) { err("DEBUG: found root dentry td == temp_vfsmnt->mnt_root %p",td); } if (IS_ROOT(td)) { err("DEBUG: found root dentry IS_ROOT(td) %p",td); } err("DEBUG: going to parent: %p -> %p",temp_vfsmnt,temp2_vfsmnt); if (temp_vfsmnt != temp2_vfsmnt) { td = getVfsMountPoint(temp_vfsmnt); err("DEBUG: going to mountpoint %s dentry=%p", td->d_name.name, td); temp_vfsmnt = temp2_vfsmnt; } else { err("DEBUG: Got to temp_vfsmnt = temp2_vfsmnt!"); } } if (td == td->d_parent) { err("DEBUG: td == td->d_parent"); break; } else if (td->d_parent == NULL) { err("DEBUG: td->d_parent == NULL"); break; } td = td->d_parent; } err("DEBUG: actual root node %s dentry=%p vfsmnt=%p",td->d_name.name,td,temp_vfsmnt); if (td == root && temp_vfsmnt == rootmnt) { err("DEBUG: Found the correct root"); } else { err("DEBUG: Found wrong root td=%p (name=%s) vfsmnt=%p", td, td->d_name.name, temp_vfsmnt); err("DEBUG: Expected root=%p (name=%s) vfsmnt=%p", root, root->d_name.name, rootmnt); } }