bool talpa_vfsmount_unlock(unsigned* m_seq) { #if defined TALPA_USE_VFSMOUNT_LOCK # if defined TALPA_VFSMOUNT_LG_BRLOCK br_read_unlock(&vfsmount_lock); # elif defined TALPA_VFSMOUNT_LOCK_BRLOCK br_read_unlock(vfsmount_lock); # else spinlock_t* talpa_vfsmount_lock_addr = (spinlock_t *)talpa_get_symbol("vfmount_lock", (void *)TALPA_VFSMOUNT_LOCK_ADDR); spin_unlock(talpa_vfsmount_lock_addr); # endif #elif defined TALPA_USE_MOUNT_LOCK seqlock_t* mount_lock_addr = (seqlock_t *)talpa_get_symbol("mount_lock", (void *)TALPA_MOUNT_LOCK_ADDR); if (need_seqretry(mount_lock_addr, *m_seq)) { *m_seq = 1; return true; } done_seqretry(mount_lock_addr, *m_seq); #else // On 2.4 we don't have vfsmount_lock - we use dcache_lock instead spin_unlock(&dcache_lock); #endif return false; }
static talpa_mount_struct* talpa_lookup_mnt_last(struct vfsmount *mnt, struct dentry *dentry) { #ifdef TALPA_HAVE_LOOKUP_MNT_LAST TALPA_PTR_FIX lookup_mnt_last_func lookup_mnt_last = (lookup_mnt_last_func)talpa_get_symbol("__lookup_mnt_last", (void *)TALPA__LOOKUP_MNT_LAST); return lookup_mnt_last(mnt, dentry); #endif #ifdef TALPA_HAVE_LOOKUP_MNT TALPA_PTR_FIX lookup_mnt_func lookup_mnt = (lookup_mnt_func)talpa_get_symbol("__lookup_mnt", (void *)TALPA__LOOKUP_MNT); return lookup_mnt(mnt, dentry, 0); #endif return NULL; }
void talpa_tasklist_unlock(void) { rwlock_t* talpa_tasklist_lock_addr = (rwlock_t *)talpa_get_symbol("tasklist_lock", (void *)TALPA_TASKLIST_LOCK_ADDR); read_unlock(talpa_tasklist_lock_addr); }
TALPA_FILENAME_T * talpa_getname(const char __user * filename ) { /* * Uses putname if available, or final_putname - but they come from the same define */ typedef TALPA_FILENAME_T * (*getname_func)(const char __user * filename); getname_func getname = (getname_func)talpa_get_symbol("getname", (void *)TALPA_GETNAME_ADDRESS); return(getname(filename)); }
void talpa_putname(TALPA_FILENAME_T* filename) { /* * Uses putname if available, or final_putname - but they come from the same define */ typedef void(*putname_func)(TALPA_FILENAME_T *); putname_func putname = (putname_func)talpa_get_symbol("putname", (void *)TALPA_PUTNAME_ADDRESS); putname(filename); }
/* * hidden vfsmnt_lock handling */ void talpa_vfsmount_lock(unsigned* m_seq) { #if defined TALPA_USE_VFSMOUNT_LOCK # if defined TALPA_VFSMOUNT_LG_BRLOCK br_read_lock(&vfsmount_lock); # elif defined TALPA_VFSMOUNT_LOCK_BRLOCK br_read_lock(vfsmount_lock); # else spinlock_t* talpa_vfsmount_lock_addr = (spinlock_t *)talpa_get_symbol("vfmount_lock", (void *)TALPA_VFSMOUNT_LOCK_ADDR); spin_lock(talpa_vfsmount_lock_addr); # endif #elif defined TALPA_USE_MOUNT_LOCK seqlock_t* mount_lock_addr = (seqlock_t *)talpa_get_symbol("mount_lock", (void *)TALPA_MOUNT_LOCK_ADDR); read_seqbegin_or_lock(mount_lock_addr,m_seq); #else // On 2.4 we don't have vfsmount_lock - we use dcache_lock instead spin_lock(&dcache_lock); #endif }
char* talpa__d_path( struct dentry *dentry, struct vfsmount *vfsmnt, struct dentry *root, struct vfsmount *rootmnt, char *buffer, int buflen, bool* nonRootNamespaceOut) { char* path; /* Get the function pointer for the real __d_path if we're going to call it. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) || (defined TALPA_HAS_DPATH) # if defined TALPA_DPATH_SLES11 typedef char *(*d_path_func)(const struct path *, struct path *, char *, int, int); # elif defined TALPA_DPATH_PATH typedef char *(*d_path_func)(const struct path *, struct path *, char *, int); # elif defined TALPA_DPATH_SUSE103 typedef char *(*d_path_func)(struct dentry *, struct vfsmount *, struct dentry *, struct vfsmount *, char *buffer, int buflen, int flags); # else typedef char *(*d_path_func)(struct dentry *, struct vfsmount *, struct dentry *, struct vfsmount *, char *buffer, int buflen); # endif # if defined TALPA_HAS_DPATH_ADDR d_path_func kernel_d_path = (d_path_func)talpa_get_symbol("__d_path", (void *)TALPA_DPATH_ADDR); # else d_path_func kernel_d_path = &__d_path; # endif # if defined TALPA_DPATH_SLES11 || defined TALPA_DPATH_PATH struct path pathPath; struct path rootPath; # endif #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) || (defined TALPA_HAS_DPATH) */ if (nonRootNamespaceOut != NULL) { *nonRootNamespaceOut = false; } #if defined HOLD_DCACHE_LOCK_WHILE_CALLING_D_PATH spin_lock(&dcache_lock); #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) || (defined TALPA_HAS_DPATH) /* Calling the real __d_path */ # if defined TALPA_DPATH_SLES11 || defined TALPA_DPATH_PATH pathPath.dentry = dentry; pathPath.mnt = vfsmnt; rootPath.dentry = root; rootPath.mnt = rootmnt; # endif # if defined TALPA_D_DNAME_DIRECT_DPATH if (dentry->d_op && dentry->d_op->d_dname) { path = d_path(&pathPath, buffer, buflen); if ( unlikely( IS_ERR(path) != 0 ) ) { critical("talpa__d_path: d_path returned an error: %ld",PTR_ERR(path)); path = NULL; } if ( NULL != path ) { return path; } } # endif /* TALPA_D_DNAME_DIRECT_DPATH */ # if defined TALPA_DPATH_SLES11 path = kernel_d_path(&pathPath, &rootPath, buffer, buflen, 0); # elif defined TALPA_DPATH_PATH path = kernel_d_path(&pathPath, &rootPath, buffer, buflen); # elif defined TALPA_DPATH_SUSE103 path = kernel_d_path(dentry, vfsmnt, root, rootmnt, buffer, buflen, 0); # else path = kernel_d_path(dentry, vfsmnt, root, rootmnt, buffer, buflen); # endif #else /* Call our own version */ path = __talpa_d_path(dentry, vfsmnt, root, rootmnt, buffer, buflen); #endif #if defined HOLD_DCACHE_LOCK_WHILE_CALLING_D_PATH spin_unlock(&dcache_lock); #endif if ( unlikely( IS_ERR(path) != 0 ) ) { critical("talpa__d_path: kernel__d_path returned an error: %ld",PTR_ERR(path)); path = NULL; } else if ( unlikely( NULL == path ) ) { #ifdef TALPA_D_DNAME_DIRECT_DPATH /* only use this as a fall-back, it will only return the relative path from a chroot * Use this in cases where kernel_d_path fails to return a valid path for bind mounts * in newer kernel in a systemd environment */ path = d_path(&pathPath, buffer, buflen); if ( unlikely( IS_ERR(path) != 0 ) ) { critical("talpa__d_path: kernel_d_path returned an error: %ld",PTR_ERR(path)); path = NULL; } if (dentry->d_op && dentry->d_op->d_dname) { dbg(" dpath=%s",path); err("dpath=%s - dentry has d_op and d_dname=%p",path,dentry->d_op->d_dname); } #endif if ( NULL == path ) { if (!IS_ROOT(dentry) && d_unhashed(dentry)) { dbg("talpa__d_path: kernel_d_path returned NULL for deleted file"); dbg(" basename=%s",dentry->d_name.name); } else { info("talpa__d_path: kernel_d_path returned NULL for non-deleted file"); info(" basename=%s",dentry->d_name.name); } } else { if (!IS_ROOT(dentry) && d_unhashed(dentry)) { dbg(" talpa__d_path: kernel_d_path returned NULL but d_path returned path %s for deleted file",path); } else { /* the systemd / containers / bind mount case. * * Now so common that we don't want to even debug log it * dbg(" talpa__d_path: kernel_d_path returned NULL but d_path returned path %s for non-deleted file",path); */ #ifdef TALPA_MNT_NAMESPACE if (NULL != getNamespaceInfo(vfsmnt) && (!S_ISDIR(dentry->d_inode->i_mode))) { /* we're in a namespace/container */ if (nonRootNamespaceOut != NULL) { *nonRootNamespaceOut = true; } } if (false) { debugPathWalk(dentry, vfsmnt, root, rootmnt); } #endif } } } return path; }