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

[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
...@@ -291,6 +291,7 @@ struct cifsTconInfo { ...@@ -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 { ...@@ -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, ...@@ -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 */
CIFSSMBQFSDeviceInfo(xid, tcon); if (!tcon->ipc) {
CIFSSMBQFSAttributeInfo(xid, tcon); CIFSSMBQFSDeviceInfo(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, ...@@ -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 @@ ...@@ -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
......
...@@ -115,7 +115,7 @@ int cifs_get_inode_info_unix(struct inode **pinode, ...@@ -115,7 +115,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
inode->i_mode = le64_to_cpu(findData.Permissions); inode->i_mode = le64_to_cpu(findData.Permissions);
/* since we set the inode type below we need to mask off /* since we set the inode type below we need to mask off
to avoid strange results if bits set above */ to avoid strange results if bits set above */
inode->i_mode &= ~S_IFMT; inode->i_mode &= ~S_IFMT;
if (type == UNIX_FILE) { if (type == UNIX_FILE) {
inode->i_mode |= S_IFREG; inode->i_mode |= S_IFREG;
} else if (type == UNIX_SYMLINK) { } else if (type == UNIX_SYMLINK) {
...@@ -575,19 +575,33 @@ int cifs_get_inode_info(struct inode **pinode, ...@@ -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) ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment