[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: Rob Shearman <rob@codeweavers.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
This commit is contained in:
@@ -291,6 +291,7 @@ struct cifsTconInfo {
|
|||||||
FILE_SYSTEM_DEVICE_INFO fsDevInfo;
|
FILE_SYSTEM_DEVICE_INFO fsDevInfo;
|
||||||
FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if fs name truncated */
|
FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if fs name truncated */
|
||||||
FILE_SYSTEM_UNIX_INFO fsUnixInfo;
|
FILE_SYSTEM_UNIX_INFO fsUnixInfo;
|
||||||
|
unsigned ipc:1; /* set if connection to IPC$ eg for RPC/PIPES */
|
||||||
unsigned retry:1;
|
unsigned retry:1;
|
||||||
unsigned nocase:1;
|
unsigned nocase:1;
|
||||||
unsigned unix_ext:1; /* if off disable Linux extensions to CIFS protocol
|
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. */
|
struct list_head llist; /* list of byte range locks we have. */
|
||||||
unsigned closePend:1; /* file is marked to close */
|
unsigned closePend:1; /* file is marked to close */
|
||||||
unsigned invalidHandle:1; /* file closed via session abend */
|
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 */
|
atomic_t wrtPending; /* handle in use - defer close */
|
||||||
struct semaphore fh_sem; /* prevents reopen race after dead ses*/
|
struct semaphore fh_sem; /* prevents reopen race after dead ses*/
|
||||||
char *search_resume_name; /* BB removeme BB */
|
char *search_resume_name; /* BB removeme BB */
|
||||||
|
@@ -2186,8 +2186,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
|
|||||||
tcon->ses = pSesInfo;
|
tcon->ses = pSesInfo;
|
||||||
|
|
||||||
/* do not care if following two calls succeed - informational */
|
/* do not care if following two calls succeed - informational */
|
||||||
|
if (!tcon->ipc) {
|
||||||
CIFSSMBQFSDeviceInfo(xid, tcon);
|
CIFSSMBQFSDeviceInfo(xid, tcon);
|
||||||
CIFSSMBQFSAttributeInfo(xid, tcon);
|
CIFSSMBQFSAttributeInfo(xid, tcon);
|
||||||
|
}
|
||||||
|
|
||||||
/* tell server which Unix caps we support */
|
/* tell server which Unix caps we support */
|
||||||
if (tcon->ses->capabilities & CAP_UNIX)
|
if (tcon->ses->capabilities & CAP_UNIX)
|
||||||
@@ -3385,6 +3387,18 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
|
|||||||
bcc_ptr = pByteArea(smb_buffer_response);
|
bcc_ptr = pByteArea(smb_buffer_response);
|
||||||
length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
|
length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
|
||||||
/* skip service field (NB: this field is always ASCII) */
|
/* 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;
|
bcc_ptr += length + 1;
|
||||||
strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
|
strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
|
||||||
if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
|
if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* vfs operations that deal with dentries
|
* 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)
|
* Author(s): Steve French (sfrench@us.ibm.com)
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or modify
|
* This library is free software; you can redistribute it and/or modify
|
||||||
|
@@ -575,19 +575,33 @@ int cifs_get_inode_info(struct inode **pinode,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct inode_operations cifs_ipc_inode_ops = {
|
||||||
|
.lookup = cifs_lookup,
|
||||||
|
};
|
||||||
|
|
||||||
/* gets root inode */
|
/* gets root inode */
|
||||||
void cifs_read_inode(struct inode *inode)
|
void cifs_read_inode(struct inode *inode)
|
||||||
{
|
{
|
||||||
int xid;
|
int xid, rc;
|
||||||
struct cifs_sb_info *cifs_sb;
|
struct cifs_sb_info *cifs_sb;
|
||||||
|
|
||||||
cifs_sb = CIFS_SB(inode->i_sb);
|
cifs_sb = CIFS_SB(inode->i_sb);
|
||||||
xid = GetXid();
|
xid = GetXid();
|
||||||
|
|
||||||
if (cifs_sb->tcon->unix_ext)
|
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
|
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 */
|
/* can not call macro FreeXid here since in a void func */
|
||||||
_FreeXid(xid);
|
_FreeXid(xid);
|
||||||
}
|
}
|
||||||
|
@@ -169,7 +169,6 @@ cifs_buf_get(void)
|
|||||||
void
|
void
|
||||||
cifs_buf_release(void *buf_to_free)
|
cifs_buf_release(void *buf_to_free)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (buf_to_free == NULL) {
|
if (buf_to_free == NULL) {
|
||||||
/* cFYI(1, ("Null buffer passed to cifs_buf_release"));*/
|
/* cFYI(1, ("Null buffer passed to cifs_buf_release"));*/
|
||||||
return;
|
return;
|
||||||
|
Reference in New Issue
Block a user