Commit 7f8ed420 authored by Steve French's avatar Steve French
Browse files

[CIFS] CIFS support for named pipes (part 1)



This allows cifs to mount to ipc shares (IPC$)
which will allow user space applications to
layer over authenticated cifs connections
(useful for Wine and others that would want
to put DCE/RPC over CIFS or run CIFS named
pipes)

Acked-by: default avatarRob Shearman <rob@codeweavers.com>
Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent 407f61a2
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -291,6 +291,7 @@ struct cifsTconInfo {
	FILE_SYSTEM_DEVICE_INFO fsDevInfo;
	FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if fs name truncated */
	FILE_SYSTEM_UNIX_INFO fsUnixInfo;
	unsigned ipc:1;		/* set if connection to IPC$ eg for RPC/PIPES */
	unsigned retry:1;
	unsigned nocase:1;
	unsigned unix_ext:1; /* if off disable Linux extensions to CIFS protocol
@@ -341,6 +342,7 @@ struct cifsFileInfo {
	struct list_head llist; /* list of byte range locks we have. */
	unsigned closePend:1;	/* file is marked to close */
	unsigned invalidHandle:1;  /* file closed via session abend */
	unsigned messageMode:1    /* for pipes: is message or byte mode */
	atomic_t wrtPending;   /* handle in use - defer close */
	struct semaphore fh_sem; /* prevents reopen race after dead ses*/
	char *search_resume_name; /* BB removeme BB */
+16 −2
Original line number Diff line number Diff line
@@ -2186,8 +2186,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
		tcon->ses = pSesInfo;

		/* do not care if following two calls succeed - informational */
		if (!tcon->ipc) {
			CIFSSMBQFSDeviceInfo(xid, tcon);
			CIFSSMBQFSAttributeInfo(xid, tcon);
		}

		/* tell server which Unix caps we support */
		if (tcon->ses->capabilities & CAP_UNIX)
@@ -3385,6 +3387,18 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
		bcc_ptr = pByteArea(smb_buffer_response);
		length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
		/* skip service field (NB: this field is always ASCII) */
		if (length == 3) {
			if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
			    (bcc_ptr[2] == 'C')) {
				cFYI(1, ("IPC connection"));
				tcon->ipc = 1;
			}
		} else if (length == 2) {
			if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
				/* the most common case */
				cFYI(1, ("disk share connection"));
			}
		}
		bcc_ptr += length + 1;
		strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
		if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
+1 −1
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
 *
 *   vfs operations that deal with dentries
 *
 *   Copyright (C) International Business Machines  Corp., 2002,2005
 *   Copyright (C) International Business Machines  Corp., 2002,2007
 *   Author(s): Steve French (sfrench@us.ibm.com)
 *
 *   This library is free software; you can redistribute it and/or modify
+18 −4
Original line number Diff line number Diff line
@@ -575,19 +575,33 @@ int cifs_get_inode_info(struct inode **pinode,
	return rc;
}

static const struct inode_operations cifs_ipc_inode_ops = {
	.lookup = cifs_lookup,
};

/* gets root inode */
void cifs_read_inode(struct inode *inode)
{
	int xid;
	int xid, rc;
	struct cifs_sb_info *cifs_sb;

	cifs_sb = CIFS_SB(inode->i_sb);
	xid = GetXid();

	if (cifs_sb->tcon->unix_ext)
		cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid);
		rc = cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid);
	else
		cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid);
		rc = cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid);
	if (rc && cifs_sb->tcon->ipc) {
		cFYI(1, ("ipc connection - fake read inode"));
		inode->i_mode |= S_IFDIR;
		inode->i_nlink = 2;
		inode->i_op = &cifs_ipc_inode_ops;
		inode->i_fop = &simple_dir_operations;
		inode->i_uid = cifs_sb->mnt_uid;
		inode->i_gid = cifs_sb->mnt_gid;
	}

	/* can not call macro FreeXid here since in a void func */
	_FreeXid(xid);
}
+0 −1
Original line number Diff line number Diff line
@@ -169,7 +169,6 @@ cifs_buf_get(void)
void
cifs_buf_release(void *buf_to_free)
{

	if (buf_to_free == NULL) {
		/* cFYI(1, ("Null buffer passed to cifs_buf_release"));*/
		return;