static int HgfsDirRelease(struct inode *inode, // IN: Inode that the file* points to struct file *file) // IN: File for the dir getting released { HgfsHandle handle; ASSERT(inode); ASSERT(file); ASSERT(file->f_dentry); ASSERT(file->f_dentry->d_sb); handle = FILE_GET_FI_P(file)->handle; HgfsReleaseFileInfo(file); return HgfsPrivateDirRelease(file, handle); }
static int HgfsRelease(struct inode *inode, // IN: Inode that this file points to struct file *file) // IN: File that is getting released { HgfsReq *req; HgfsHandle handle; HgfsOp opUsed; HgfsStatus replyStatus; int result = 0; ASSERT(inode); ASSERT(file); ASSERT(file->f_dentry); ASSERT(file->f_dentry->d_sb); handle = FILE_GET_FI_P(file)->handle; LOG(6, (KERN_DEBUG "VMware hgfs: HgfsRelease: close fh %u\n", handle)); /* * This may be our last open handle to an inode, so we should flush our * dirty pages before closing it. */ compat_filemap_write_and_wait(inode->i_mapping); HgfsReleaseFileInfo(file); req = HgfsGetNewRequest(); if (!req) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRelease: out of memory while " "getting new request\n")); result = -ENOMEM; goto out; } retry: opUsed = hgfsVersionClose; if (opUsed == HGFS_OP_CLOSE_V3) { HgfsRequest *header; HgfsRequestCloseV3 *request; header = (HgfsRequest *)(HGFS_REQ_PAYLOAD(req)); header->id = req->id; header->op = opUsed; request = (HgfsRequestCloseV3 *)(HGFS_REQ_PAYLOAD_V3(req)); request->file = handle; request->reserved = 0; req->payloadSize = HGFS_REQ_PAYLOAD_SIZE_V3(request); } else { HgfsRequestClose *request; request = (HgfsRequestClose *)(HGFS_REQ_PAYLOAD(req)); request->header.id = req->id; request->header.op = opUsed; request->file = handle; req->payloadSize = sizeof *request; } /* Send the request and process the reply. */ result = HgfsSendRequest(req); if (result == 0) { /* Get the reply. */ replyStatus = HgfsReplyStatus(req); result = HgfsStatusConvertToLinux(replyStatus); switch (result) { case 0: LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRelease: released handle %u\n", handle)); break; case -EPROTO: /* Retry with older version(s). Set globally. */ if (opUsed == HGFS_OP_CLOSE_V3) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRelease: Version 3 not " "supported. Falling back to version 1.\n")); hgfsVersionClose = HGFS_OP_CLOSE; goto retry; } break; default: LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRelease: failed handle %u\n", handle)); break; } } else if (result == -EIO) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRelease: timed out\n")); } else if (result == -EPROTO) { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRelease: server " "returned error: %d\n", result)); } else { LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRelease: unknown error: " "%d\n", result)); } out: HgfsFreeRequest(req); return result; }