Esempio n. 1
0
static int
HgfsFollowlink(struct dentry *dentry, // IN: Dentry containing link
               struct nameidata *nd)  // OUT: Contains target dentry
#endif
{
   HgfsAttrInfo attr;
   char *fileName = NULL;
   int error;

   ASSERT(dentry);
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)
   ASSERT(nd);
#endif

   if (!dentry) {
      LOG(4, (KERN_DEBUG "VMware hgfs: HgfsFollowlink: null input\n"));
      error = -EINVAL;
      goto out;
   }

   LOG(6, (KERN_DEBUG "VMware hgfs: %s: calling HgfsPrivateGetattr %s\n",
           __func__, dentry->d_name.name));
   error = HgfsPrivateGetattr(dentry, &attr, &fileName);
   LOG(6, (KERN_DEBUG "VMware hgfs: %s: HgfsPrivateGetattr %s ret %d\n",
           __func__, dentry->d_name.name, error));
   if (!error) {

      /* Let's make sure we got called on a symlink. */
      if (attr.type != HGFS_FILE_TYPE_SYMLINK || fileName == NULL) {
         LOG(6, (KERN_DEBUG "VMware hgfs: HgfsFollowlink: got called "
                 "on something that wasn't a symlink\n"));
         error = -EINVAL;
         kfree(fileName);
      } else {
         LOG(6, (KERN_DEBUG "VMware hgfs: %s: calling nd_set_link %s\n",
                 __func__, fileName));
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
         *cookie = fileName;
#else
         nd_set_link(nd, fileName);
#endif
      }
   }

out:
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
   if (!error) {
      return *cookie;
   } else {
      return ERR_PTR(error);
   }
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13)
   return ERR_PTR(error);
#else
   return error;
#endif
}
Esempio n. 2
0
static int
HgfsFollowlink(struct dentry *dentry, // IN: Dentry containing link
               struct nameidata *nd)  // OUT: Contains target dentry
#endif
{
   HgfsAttrInfo attr;
   char *fileName = NULL;
   int error;

   ASSERT(dentry);
   ASSERT(nd);

   if (!dentry) {
      LOG(4, (KERN_DEBUG "VMware hgfs: HgfsFollowlink: null input\n"));
      error = -EINVAL;
      goto out;
   }

   LOG(6, (KERN_DEBUG "VMware hgfs: HgfsFollowlink: calling "
           "HgfsPrivateGetattr\n"));
   error = HgfsPrivateGetattr(dentry, &attr, &fileName);
   if (!error) {

      /* Let's make sure we got called on a symlink. */
      if (attr.type != HGFS_FILE_TYPE_SYMLINK || fileName == NULL) {
         LOG(6, (KERN_DEBUG "VMware hgfs: HgfsFollowlink: got called "
                 "on something that wasn't a symlink\n"));
         error = -EINVAL;
      } else {
         LOG(6, (KERN_DEBUG "VMware hgfs: HgfsFollowlink: calling "
                 "vfs_follow_link\n"));
         error = vfs_follow_link(nd, fileName);
      }
      kfree(fileName);
   }
  out:

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13)
   return ERR_PTR(error);
#else
   return error;
#endif
}
Esempio n. 3
0
static int
HgfsReadlink(struct dentry *dentry,  // IN:  Dentry containing link
             char __user *buffer,    // OUT: User buffer to copy link into
             int buflen)             // IN:  Length of user buffer

{
   HgfsAttrInfo attr;
   char *fileName = NULL;
   int error;

   ASSERT(dentry);
   ASSERT(buffer);

   if (!dentry) {
      LOG(4, (KERN_DEBUG "VMware hgfs: HgfsReadlink: null input\n"));
      return -EINVAL;
   }

   LOG(6, (KERN_DEBUG "VMware hgfs: %s: calling HgfsPrivateGetattr %s\n",
           __func__, dentry->d_name.name));
   error = HgfsPrivateGetattr(dentry, &attr, &fileName);
   if (!error) {

      /* Let's make sure we got called on a symlink. */
      if (attr.type != HGFS_FILE_TYPE_SYMLINK || fileName == NULL) {
         LOG(6, (KERN_DEBUG "VMware hgfs: HgfsReadlink: got called "
                 "on something that wasn't a symlink\n"));
         error = -EINVAL;
      } else {
         LOG(6, (KERN_DEBUG "VMware hgfs: %s: calling vfs_readlink %s\n",
                 __func__, fileName));
         error = HGFS_DO_READLINK(dentry, buffer, buflen, fileName);
         LOG(6, (KERN_DEBUG "VMware hgfs: %s: vfs_readlink %s ret %dn",
                 __func__, fileName, error));
      }
      kfree(fileName);
   }
   return error;
}
Esempio n. 4
0
static int
HgfsGetRootDentry(struct super_block *sb,       // IN: Super block object
                  struct dentry **rootDentry)   // OUT: Root dentry
{
   int result = -ENOMEM;
   struct inode *rootInode;
   struct dentry *tempRootDentry = NULL;
   struct HgfsAttrInfo rootDentryAttr;
   HgfsInodeInfo *iinfo;

   ASSERT(sb);
   ASSERT(rootDentry);

   LOG(6, (KERN_DEBUG "VMware hgfs: %s: entered\n", __func__));

   rootInode = HgfsGetInode(sb, HGFS_ROOT_INO);
   if (rootInode == NULL) {
      LOG(6, (KERN_DEBUG "VMware hgfs: %s: Could not get the root inode\n",
             __func__));
      goto exit;
   }

   /*
    * On an allocation failure in read_super, the inode will have been
    * marked "bad". If it was, we certainly don't want to start playing with
    * the HgfsInodeInfo. So quietly put the inode back and fail.
    */
   if (is_bad_inode(rootInode)) {
      LOG(6, (KERN_DEBUG "VMware hgfs: %s: encountered bad inode\n",
             __func__));
      goto exit;
   }

   tempRootDentry = d_alloc_root(rootInode);
   if (tempRootDentry == NULL) {
      LOG(4, (KERN_WARNING "VMware hgfs: %s: Could not get "
              "root dentry\n", __func__));
      goto exit;
   }

   rootInode = NULL;

   result = HgfsPrivateGetattr(tempRootDentry, &rootDentryAttr, NULL);
   if (result) {
      LOG(4, (KERN_WARNING "VMware hgfs: HgfsReadSuper: Could not"
             "instantiate the root dentry\n"));
      goto exit;
   }

   iinfo = INODE_GET_II_P(tempRootDentry->d_inode);
   iinfo->isFakeInodeNumber = FALSE;
   iinfo->isReferencedInode = TRUE;

   if (rootDentryAttr.mask & HGFS_ATTR_VALID_FILEID) {
      iinfo->hostFileId = rootDentryAttr.hostFileId;
   }

   HgfsChangeFileAttributes(tempRootDentry->d_inode, &rootDentryAttr);
   HgfsDentryAgeReset(tempRootDentry);
   tempRootDentry->d_op = &HgfsDentryOperations;

   *rootDentry = tempRootDentry;
   result = 0;

   LOG(6, (KERN_DEBUG "VMware hgfs: %s: finished\n", __func__));
exit:
   if (result) {
      iput(rootInode);
      dput(tempRootDentry);
      *rootDentry = NULL;
   }
   return result;
}