Beispiel #1
0
int
smb3_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
		       struct cifs_sb_info *cifs_sb, const unsigned char *path,
		       char *pbuf, unsigned int *pbytes_written)
{
	int rc;
	struct cifs_fid fid;
	struct cifs_open_parms oparms;
	struct cifs_io_parms io_parms;
	int create_options = CREATE_NOT_DIR;
	__le16 *utf16_path;
	__u8 oplock = SMB2_OPLOCK_LEVEL_EXCLUSIVE;
	struct kvec iov[2];

	if (backup_cred(cifs_sb))
		create_options |= CREATE_OPEN_BACKUP_INTENT;

	cifs_dbg(FYI, "%s: path: %s\n", __func__, path);

	utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
	if (!utf16_path)
		return -ENOMEM;

	oparms.tcon = tcon;
	oparms.cifs_sb = cifs_sb;
	oparms.desired_access = GENERIC_WRITE;
	oparms.create_options = create_options;
	oparms.disposition = FILE_CREATE;
	oparms.fid = &fid;
	oparms.reconnect = false;

	rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL);
	if (rc) {
		kfree(utf16_path);
		return rc;
	}

	io_parms.netfid = fid.netfid;
	io_parms.pid = current->tgid;
	io_parms.tcon = tcon;
	io_parms.offset = 0;
	io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
	io_parms.persistent_fid = fid.persistent_fid;
	io_parms.volatile_fid = fid.volatile_fid;

	/* iov[0] is reserved for smb header */
	iov[1].iov_base = pbuf;
	iov[1].iov_len = CIFS_MF_SYMLINK_FILE_SIZE;

	rc = SMB2_write(xid, &io_parms, pbytes_written, iov, 1);

	/* Make sure we wrote all of the symlink data */
	if ((rc == 0) && (*pbytes_written != CIFS_MF_SYMLINK_FILE_SIZE))
		rc = -EIO;

	SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);

	kfree(utf16_path);
	return rc;
}
Beispiel #2
0
static int
smb2_open_op_close(const unsigned int xid, struct cifs_tcon *tcon,
		   struct cifs_sb_info *cifs_sb, const char *full_path,
		   __u32 desired_access, __u32 create_disposition,
		   __u32 file_attributes, __u32 create_options,
		   void *data, int command)
{
	int rc, tmprc = 0;
	u64 persistent_fid, volatile_fid;
	__le16 *utf16_path;

	utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
	if (!utf16_path)
		return -ENOMEM;

	rc = SMB2_open(xid, tcon, utf16_path, &persistent_fid, &volatile_fid,
		       desired_access, create_disposition, file_attributes,
		       create_options);
	if (rc) {
		kfree(utf16_path);
		return rc;
	}

	switch (command) {
	case SMB2_OP_DELETE:
		break;
	case SMB2_OP_QUERY_INFO:
		tmprc = SMB2_query_info(xid, tcon, persistent_fid,
					volatile_fid,
					(struct smb2_file_all_info *)data);
		break;
	case SMB2_OP_MKDIR:
		/*
		 * Directories are created through parameters in the
		 * SMB2_open() call.
		 */
		break;
	default:
		cERROR(1, "Invalid command");
		break;
	}

	rc = SMB2_close(xid, tcon, persistent_fid, volatile_fid);
	if (tmprc)
		rc = tmprc;
	kfree(utf16_path);
	return rc;
}
Beispiel #3
0
static int
smb2_open_op_close(const unsigned int xid, struct cifs_tcon *tcon,
		   struct cifs_sb_info *cifs_sb, const char *full_path,
		   __u32 desired_access, __u32 create_disposition,
		   __u32 create_options, void *data, int command)
{
	int rc, tmprc = 0;
	__le16 *utf16_path;
	__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
	struct cifs_open_parms oparms;
	struct cifs_fid fid;

	utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
	if (!utf16_path)
		return -ENOMEM;

	oparms.tcon = tcon;
	oparms.desired_access = desired_access;
	oparms.share_access = FILE_SHARE_ALL;
	oparms.disposition = create_disposition;
	oparms.create_options = create_options;
	oparms.fid = &fid;
	oparms.reconnect = false;

	rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL);
	if (rc) {
		kfree(utf16_path);
		return rc;
	}

	switch (command) {
	case SMB2_OP_DELETE:
		break;
	case SMB2_OP_QUERY_INFO:
		tmprc = SMB2_query_info(xid, tcon, fid.persistent_fid,
					fid.volatile_fid,
					(struct smb2_file_all_info *)data);
		break;
	case SMB2_OP_MKDIR:
		/*
		 * Directories are created through parameters in the
		 * SMB2_open() call.
		 */
		break;
	case SMB2_OP_RENAME:
		tmprc = SMB2_rename(xid, tcon, fid.persistent_fid,
				    fid.volatile_fid, (__le16 *)data);
		break;
	case SMB2_OP_HARDLINK:
		tmprc = SMB2_set_hardlink(xid, tcon, fid.persistent_fid,
					  fid.volatile_fid, (__le16 *)data);
		break;
	case SMB2_OP_SET_EOF:
		tmprc = SMB2_set_eof(xid, tcon, fid.persistent_fid,
				     fid.volatile_fid, current->tgid,
				     (__le64 *)data, false);
		break;
	case SMB2_OP_SET_INFO:
		tmprc = SMB2_set_info(xid, tcon, fid.persistent_fid,
				      fid.volatile_fid,
				      (FILE_BASIC_INFO *)data);
		break;
	default:
		cifs_dbg(VFS, "Invalid command\n");
		break;
	}

	rc = SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
	if (tmprc)
		rc = tmprc;
	kfree(utf16_path);
	return rc;
}
Beispiel #4
0
int
smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
		      struct cifs_sb_info *cifs_sb, const unsigned char *path,
		      char *pbuf, unsigned int *pbytes_read)
{
	int rc;
	struct cifs_fid fid;
	struct cifs_open_parms oparms;
	struct cifs_io_parms io_parms;
	int buf_type = CIFS_NO_BUFFER;
	__le16 *utf16_path;
	__u8 oplock = SMB2_OPLOCK_LEVEL_II;
	struct smb2_file_all_info *pfile_info = NULL;

	oparms.tcon = tcon;
	oparms.cifs_sb = cifs_sb;
	oparms.desired_access = GENERIC_READ;
	oparms.create_options = CREATE_NOT_DIR;
	if (backup_cred(cifs_sb))
		oparms.create_options |= CREATE_OPEN_BACKUP_INTENT;
	oparms.disposition = FILE_OPEN;
	oparms.fid = &fid;
	oparms.reconnect = false;

	utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
	if (utf16_path == NULL)
		return -ENOMEM;

	pfile_info = kzalloc(sizeof(struct smb2_file_all_info) + PATH_MAX * 2,
			     GFP_KERNEL);

	if (pfile_info == NULL) {
		kfree(utf16_path);
		return  -ENOMEM;
	}

	rc = SMB2_open(xid, &oparms, utf16_path, &oplock, pfile_info, NULL);
	if (rc)
		goto qmf_out_open_fail;

	if (pfile_info->EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) {
		/* it's not a symlink */
		rc = -ENOENT; /* Is there a better rc to return? */
		goto qmf_out;
	}

	io_parms.netfid = fid.netfid;
	io_parms.pid = current->tgid;
	io_parms.tcon = tcon;
	io_parms.offset = 0;
	io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
	io_parms.persistent_fid = fid.persistent_fid;
	io_parms.volatile_fid = fid.volatile_fid;
	rc = SMB2_read(xid, &io_parms, pbytes_read, &pbuf, &buf_type);
qmf_out:
	SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
qmf_out_open_fail:
	kfree(utf16_path);
	kfree(pfile_info);
	return rc;
}