~ubuntu-branches/ubuntu/quantal/open-vm-tools/quantal-201207201942

« back to all changes in this revision

Viewing changes to modules/linux/vmhgfs/fsutil.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2009-10-18 12:28:19 UTC
  • mfrom: (1.1.7 upstream) (2.4.9 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091018122819-00vqew6m0ztpqcqp
Tags: 2009.10.15-201664-1
MergingĀ upstreamĀ versionĀ 2009.10.15-201664.

Show diffs side-by-side

added added

removed removed

Lines of Context:
47
47
#include "hgfsProto.h"
48
48
#include "vm_basic_types.h"
49
49
 
50
 
static struct inode *HgfsInodeLookup(struct super_block *sb,
51
 
                                     ino_t ino);
52
50
static void HgfsSetFileType(struct inode *inode,
53
51
                            HgfsAttrInfo const *attr);
54
52
static int HgfsUnpackGetattrReply(HgfsReq *req,
55
 
                                  HgfsAttrInfo *attr);
 
53
                                  HgfsAttrInfo *attr,
 
54
                                  char **fileName);
56
55
static int HgfsPackGetattrRequest(HgfsReq *req,
57
56
                                  struct dentry *dentry,
58
57
                                  Bool allowHandleReuse,
66
65
/*
67
66
 *----------------------------------------------------------------------
68
67
 *
69
 
 * HgfsInodeLookup --
70
 
 *
71
 
 *    The equivalent of ilookup() in the Linux kernel. We have an HGFS
72
 
 *    specific implementation in order to hack around the lack of
73
 
 *    ilookup() on older kernels.
74
 
 *
75
 
 * Results:
76
 
 *    Pointer to the VFS inode using the current inode number if it
77
 
 *    already exists in the inode cache, NULL otherwise.
78
 
 *
79
 
 * Side effects:
80
 
 *    None
81
 
 *
82
 
 *----------------------------------------------------------------------
83
 
 */
84
 
 
85
 
static struct inode *
86
 
HgfsInodeLookup(struct super_block *sb,  // IN: Superblock of this fs
87
 
                ino_t ino)               // IN: Inode number to look up
88
 
{
89
 
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 42)
90
 
   return ilookup(sb, ino);
91
 
#else
92
 
   struct inode *inode;
93
 
   HgfsInodeInfo *iinfo;
94
 
 
95
 
   /*
96
 
    * Note that returning NULL in both of these cases will make the
97
 
    * caller think that no such inode exists, which is correct. In the first
98
 
    * case, we failed to allocate an inode inside iget(), meaning the inode
99
 
    * number didn't already exist in the inode cache. In the second case, the
100
 
    * inode got marked bad inside read_inode, also indicative of a new inode
101
 
    * allocation.
102
 
    */
103
 
   inode = HgfsGetInode(sb, ino);
104
 
   if (inode == NULL) {
105
 
      LOG(4, (KERN_DEBUG "VMware hgfs: HgfsInodeLookup: iget ran out of "
106
 
              "memory and returned NULL\n"));
107
 
      return NULL;
108
 
   }
109
 
   if (is_bad_inode(inode)) {
110
 
      LOG(4, (KERN_DEBUG "VMware hgfs: HgfsInodeLookup: inode marked bad\n"));
111
 
      goto iput_and_exit;
112
 
   }
113
 
 
114
 
   /*
115
 
    * Our read_inode function should guarantee that if we're here, iinfo should
116
 
    * have been allocated already.
117
 
    */
118
 
   iinfo = INODE_GET_II_P(inode);
119
 
   ASSERT(iinfo);
120
 
   if (iinfo == NULL) {
121
 
      LOG(4, (KERN_DEBUG "VMware hgfs: HgfsInodeLookup: found corrupt inode, "
122
 
              "bailing out\n"));
123
 
      goto iput_and_exit;
124
 
   }
125
 
 
126
 
   /*
127
 
    * It's HGFS's job to make sure this is set to TRUE in all inodes on which
128
 
    * we hold a reference. If it is set to TRUE, we return the inode, just as
129
 
    * ilookup() does.
130
 
    *
131
 
    * XXX: Note that there exists a race here and in HgfsIget (between the time
132
 
    * that the inode is unlocked and isReferencedInode is set), but I'm hoping
133
 
    * that it doesn't matter because anyone executing this code can't posibly
134
 
    * be "CONFIG_PREEMPT=y".
135
 
    */
136
 
   if (iinfo->isReferencedInode) {
137
 
      goto exit;
138
 
   }
139
 
 
140
 
  iput_and_exit:
141
 
   iput(inode);
142
 
   inode = NULL;
143
 
 
144
 
  exit:
145
 
   return inode;
146
 
#endif
147
 
}
148
 
 
149
 
 
150
 
/*
151
 
 *----------------------------------------------------------------------
152
 
 *
153
68
 * HgfsSetFileType --
154
69
 *
155
70
 *    Set file type in inode according to the hgfs attributes.
227
142
 */
228
143
static int
229
144
HgfsUnpackGetattrReply(HgfsReq *req,        // IN: Reply packet
230
 
                       HgfsAttrInfo *attr)  // IN/OUT: Attributes
 
145
                       HgfsAttrInfo *attr,  // IN/OUT: Attributes
 
146
                       char **fileName)     // OUT: file name
231
147
{
232
148
   int result;
233
149
   char *name = NULL;
267
183
      }
268
184
   }
269
185
 
270
 
   if (length != 0) {
271
 
 
272
 
      attr->fileName = kmalloc(length + 1, GFP_KERNEL);
273
 
      if (attr->fileName == NULL) {
274
 
         LOG(4, (KERN_DEBUG "VMware hgfs: HgfsUnpackGetattrReply: out of "
275
 
                 "memory allocating symlink target name, ignoring\n"));
276
 
         return -ENOMEM;
 
186
   if (fileName) {
 
187
      if (length != 0) {
 
188
 
 
189
         *fileName = kmalloc(length + 1, GFP_KERNEL);
 
190
         if (*fileName == NULL) {
 
191
            LOG(4, (KERN_DEBUG "VMware hgfs: HgfsUnpackGetattrReply: out of "
 
192
                    "memory allocating symlink target name, ignoring\n"));
 
193
            return -ENOMEM;
 
194
         }
 
195
 
 
196
         /* Copy and convert. From now on, the symlink target is in UTF8. */
 
197
         memcpy(*fileName, name, length);
 
198
         CPNameLite_ConvertFrom(*fileName, length, '/');
 
199
         (*fileName)[length] = '\0';
 
200
      } else {
 
201
         *fileName = NULL;
277
202
      }
278
 
 
279
 
      /* Copy and convert. From now on, the symlink target is in UTF8. */
280
 
      memcpy(attr->fileName, name, length);
281
 
      CPNameLite_ConvertFrom(attr->fileName, length, '/');
282
 
      attr->fileName[length] = '\0';
283
203
   }
284
204
 
285
205
   return 0;
790
710
 *    for the indicated remote name, and if it succeeds copy the
791
711
 *    results of the getattr into the provided HgfsAttrInfo.
792
712
 *
793
 
 *    attr->fileName will be allocated on success if the file is a
794
 
 *    symlink; it's the caller's duty to free it.
 
713
 *    fileName (if supplied) will be set to a newly allocated string
 
714
 *    if the file is a symlink; it's the caller's duty to free it.
795
715
 *
796
716
 * Results:
797
717
 *    Returns zero on success, or a negative error on failure.
804
724
 
805
725
int
806
726
HgfsPrivateGetattr(struct dentry *dentry,  // IN: Dentry containing name
807
 
                   HgfsAttrInfo *attr)     // OUT: Attr to copy into
 
727
                   HgfsAttrInfo *attr,     // OUT: Attr to copy into
 
728
                   char **fileName)        // OUT: pointer to allocated file name
808
729
{
809
730
   struct HgfsSuperInfo *si;
810
731
   HgfsReq *req;
850
771
       */
851
772
      switch (result) {
852
773
      case 0:
853
 
         result = HgfsUnpackGetattrReply(req, attr);
 
774
         result = HgfsUnpackGetattrReply(req, attr, fileName);
854
775
         break;
855
776
      case -EBADF:
856
777
         /*
952
873
       * XXX: Is this worth the value? We're mixing server-provided inode
953
874
       * numbers with our own randomly chosen inode numbers.
954
875
       *
955
 
       * XXX: This logic is also racy. After our call to HgfsInodeLookup(), it's
 
876
       * XXX: This logic is also racy. After our call to ilookup(), it's
956
877
       * possible another caller came in and grabbed that inode number, which
957
878
       * will cause us to collide in iget() and step on their inode.
958
879
       */
959
880
      if (attr->mask & HGFS_ATTR_VALID_FILEID) {
960
881
         struct inode *oldInode;
961
882
 
962
 
         oldInode = HgfsInodeLookup(sb, attr->hostFileId);
 
883
         oldInode = ilookup(sb, attr->hostFileId);
963
884
         if (oldInode) {
964
 
 
965
885
            /*
966
886
             * If this inode's inode number was generated via iunique(), we
967
887
             * have a collision and cannot use the server's inode number.
968
 
             * Otherwise, we should reuse this inode.
 
888
             * Or, if the dentry is for a directory, we should not reuse the
 
889
             * inode in case there are two directory dentries referring to the
 
890
             * same inode. Otherwise, we should reuse this inode.
 
891
             *
 
892
             * Be careful of the following setting when resuing inodes:
 
893
             *     host dir -> share name
 
894
             *     C:/parent/         -> host1
 
895
             *     C:/parent/child/   -> host2
 
896
             * /mnt/hgfs/host1/child and /mnt/hgfs/host2 are actually the
 
897
             * same directory in host. It also happens to the files in child.
 
898
             * Here, we should prevent the inode reusing because in Linux kernel
 
899
             * no inode can be pointed to by multiple directory entries; whereas
 
900
             * it is OK to do that for the files in /mnt/hgfs/child/.
969
901
             */
970
902
            iinfo = INODE_GET_II_P(oldInode);
971
 
            if (iinfo->isFakeInodeNumber) {
972
 
               LOG(6, (KERN_DEBUG "VMware hgfs: HgfsIget: found existing "
973
 
                       "iuniqued inode %"FMT64"d, generating new one\n",
974
 
                       attr->hostFileId));
 
903
            if (iinfo->isFakeInodeNumber ||
 
904
                attr->type == HGFS_FILE_TYPE_DIRECTORY) {
 
905
               LOG(6, ("VMware hgfs: %s: found existing iuniqued inode or "
 
906
                       "directory inode %"FMT64"d, generating new one\n",
 
907
                       __func__, attr->hostFileId));
975
908
               ino = iunique(sb, HGFS_RESERVED_INO);
976
909
               isFakeInodeNumber = TRUE;
977
910
            } else {
1076
1009
      int error;
1077
1010
 
1078
1011
      LOG(6, (KERN_DEBUG "VMware hgfs: HgfsInstantiate: issuing getattr\n"));
1079
 
      newAttr.fileName = NULL;
1080
 
      error = HgfsPrivateGetattr(dentry, &newAttr);
 
1012
      error = HgfsPrivateGetattr(dentry, &newAttr, NULL);
1081
1013
      if (error) {
1082
1014
         return error;
1083
1015
      }
1084
 
      kfree(newAttr.fileName);
1085
1016
      attr = &newAttr;
1086
1017
   }
1087
1018
 
1401
1332
   fileInfo->mode = HGFS_OPEN_MODE_ACCMODE(mode) + 1;
1402
1333
   FILE_SET_FI_P(file, fileInfo);
1403
1334
 
 
1335
   /* So that readdir() reissues open request */
 
1336
   fileInfo->isStale = TRUE;
 
1337
 
1404
1338
   /*
1405
1339
    * I don't think we need any VFS locks since we're only touching the HGFS
1406
1340
    * specific state. But we should still acquire our own lock.
1681
1615
 *
1682
1616
 * HgfsGetInode --
1683
1617
 *
1684
 
 *    This function replaces iget() and should be called instead of it. In newer
1685
 
 *    kernels that have removed the iget() interface,  GetInode() obtains an inode
1686
 
 *    and if it is a new one, then initializes the inode by calling
1687
 
 *    HgfsDoReadInode(). In older kernels that support the iget() interface,
1688
 
 *    HgfsDoReadInode() is called by iget() internally.
 
1618
 *    This function replaces iget() and should be called instead of it.
 
1619
 *    HgfsGetInode() obtains an inode and, if it is a new one, initializes
 
1620
 *    it calling HgfsDoReadInode().
1689
1621
 *
1690
1622
 * Results:
1691
1623
 *    A new inode object on success, NULL on error.
1700
1632
HgfsGetInode(struct super_block *sb, // IN: file system superblock object
1701
1633
             ino_t ino)              // IN: inode number to assign to new inode
1702
1634
{
1703
 
#ifdef VMW_USE_IGET_LOCKED
1704
1635
   struct inode *inode;
1705
1636
 
1706
1637
   inode = iget_locked(sb, ino);
1709
1640
      unlock_new_inode(inode);
1710
1641
   }
1711
1642
   return inode;
1712
 
#else
1713
 
   return iget(sb, ino);
1714
 
#endif
1715
1643
}
1716
1644
 
1717
1645
 
1749
1677
    * allocation and mark the inode "bad" if the allocation fails. This'll
1750
1678
    * make all subsequent operations on the inode fail, which is what we want.
1751
1679
    */
1752
 
#ifndef VMW_EMBED_INODE
1753
 
   iinfo = kmem_cache_alloc(hgfsInodeCache, GFP_KERNEL);
1754
 
   if (!iinfo) {
1755
 
      LOG(4, (KERN_DEBUG "VMware hgfs: HgfsDoReadInode: no memory for "
1756
 
              "iinfo!\n"));
1757
 
      make_bad_inode(inode);
1758
 
      return;
1759
 
   }
1760
 
#endif
1761
1680
   INODE_SET_II_P(inode, iinfo);
1762
1681
   INIT_LIST_HEAD(&iinfo->files);
1763
1682
   iinfo->hostFileId = 0;