aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2007-09-28 18:28:55 -0400
committerSteve French <sfrench@us.ibm.com>2007-09-28 18:28:55 -0400
commit7f8ed420f80c91176dfd27c8089f22cab5c9ba78 (patch)
treebd3cea6554c3e59230c83fa7e9912740e178b00c /fs/cifs
parent407f61a2b482ab9a6d03549ab9513e4a823ae4a2 (diff)
[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>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cifsglob.h2
-rw-r--r--fs/cifs/connect.c18
-rw-r--r--fs/cifs/dir.c2
-rw-r--r--fs/cifs/inode.c22
-rw-r--r--fs/cifs/misc.c1
5 files changed, 37 insertions, 8 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index bb468de4f474..f55be8efa26d 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -291,6 +291,7 @@ struct cifsTconInfo {
291 FILE_SYSTEM_DEVICE_INFO fsDevInfo; 291 FILE_SYSTEM_DEVICE_INFO fsDevInfo;
292 FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if fs name truncated */ 292 FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if fs name truncated */
293 FILE_SYSTEM_UNIX_INFO fsUnixInfo; 293 FILE_SYSTEM_UNIX_INFO fsUnixInfo;
294 unsigned ipc:1; /* set if connection to IPC$ eg for RPC/PIPES */
294 unsigned retry:1; 295 unsigned retry:1;
295 unsigned nocase:1; 296 unsigned nocase:1;
296 unsigned unix_ext:1; /* if off disable Linux extensions to CIFS protocol 297 unsigned unix_ext:1; /* if off disable Linux extensions to CIFS protocol
@@ -341,6 +342,7 @@ struct cifsFileInfo {
341 struct list_head llist; /* list of byte range locks we have. */ 342 struct list_head llist; /* list of byte range locks we have. */
342 unsigned closePend:1; /* file is marked to close */ 343 unsigned closePend:1; /* file is marked to close */
343 unsigned invalidHandle:1; /* file closed via session abend */ 344 unsigned invalidHandle:1; /* file closed via session abend */
345 unsigned messageMode:1 /* for pipes: is message or byte mode */
344 atomic_t wrtPending; /* handle in use - defer close */ 346 atomic_t wrtPending; /* handle in use - defer close */
345 struct semaphore fh_sem; /* prevents reopen race after dead ses*/ 347 struct semaphore fh_sem; /* prevents reopen race after dead ses*/
346 char *search_resume_name; /* BB removeme BB */ 348 char *search_resume_name; /* BB removeme BB */
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index e43cb880f54a..21cac15ed9a7 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2186,8 +2186,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2186 tcon->ses = pSesInfo; 2186 tcon->ses = pSesInfo;
2187 2187
2188 /* do not care if following two calls succeed - informational */ 2188 /* do not care if following two calls succeed - informational */
2189 CIFSSMBQFSDeviceInfo(xid, tcon); 2189 if (!tcon->ipc) {
2190 CIFSSMBQFSAttributeInfo(xid, tcon); 2190 CIFSSMBQFSDeviceInfo(xid, tcon);
2191 CIFSSMBQFSAttributeInfo(xid, tcon);
2192 }
2191 2193
2192 /* tell server which Unix caps we support */ 2194 /* tell server which Unix caps we support */
2193 if (tcon->ses->capabilities & CAP_UNIX) 2195 if (tcon->ses->capabilities & CAP_UNIX)
@@ -3385,6 +3387,18 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3385 bcc_ptr = pByteArea(smb_buffer_response); 3387 bcc_ptr = pByteArea(smb_buffer_response);
3386 length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2); 3388 length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
3387 /* skip service field (NB: this field is always ASCII) */ 3389 /* skip service field (NB: this field is always ASCII) */
3390 if (length == 3) {
3391 if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
3392 (bcc_ptr[2] == 'C')) {
3393 cFYI(1, ("IPC connection"));
3394 tcon->ipc = 1;
3395 }
3396 } else if (length == 2) {
3397 if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
3398 /* the most common case */
3399 cFYI(1, ("disk share connection"));
3400 }
3401 }
3388 bcc_ptr += length + 1; 3402 bcc_ptr += length + 1;
3389 strncpy(tcon->treeName, tree, MAX_TREE_SIZE); 3403 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
3390 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) { 3404 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index db5287abc30f..99321ab439d2 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * vfs operations that deal with dentries 4 * vfs operations that deal with dentries
5 * 5 *
6 * Copyright (C) International Business Machines Corp., 2002,2005 6 * Copyright (C) International Business Machines Corp., 2002,2007
7 * Author(s): Steve French (sfrench@us.ibm.com) 7 * Author(s): Steve French (sfrench@us.ibm.com)
8 * 8 *
9 * This library is free software; you can redistribute it and/or modify 9 * This library is free software; you can redistribute it and/or modify
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 552d68b9d6f4..ece17ca00d08 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -115,7 +115,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
115 inode->i_mode = le64_to_cpu(findData.Permissions); 115 inode->i_mode = le64_to_cpu(findData.Permissions);
116 /* since we set the inode type below we need to mask off 116 /* since we set the inode type below we need to mask off
117 to avoid strange results if bits set above */ 117 to avoid strange results if bits set above */
118 inode->i_mode &= ~S_IFMT; 118 inode->i_mode &= ~S_IFMT;
119 if (type == UNIX_FILE) { 119 if (type == UNIX_FILE) {
120 inode->i_mode |= S_IFREG; 120 inode->i_mode |= S_IFREG;
121 } else if (type == UNIX_SYMLINK) { 121 } else if (type == UNIX_SYMLINK) {
@@ -575,19 +575,33 @@ int cifs_get_inode_info(struct inode **pinode,
575 return rc; 575 return rc;
576} 576}
577 577
578static const struct inode_operations cifs_ipc_inode_ops = {
579 .lookup = cifs_lookup,
580};
581
578/* gets root inode */ 582/* gets root inode */
579void cifs_read_inode(struct inode *inode) 583void cifs_read_inode(struct inode *inode)
580{ 584{
581 int xid; 585 int xid, rc;
582 struct cifs_sb_info *cifs_sb; 586 struct cifs_sb_info *cifs_sb;
583 587
584 cifs_sb = CIFS_SB(inode->i_sb); 588 cifs_sb = CIFS_SB(inode->i_sb);
585 xid = GetXid(); 589 xid = GetXid();
586 590
587 if (cifs_sb->tcon->unix_ext) 591 if (cifs_sb->tcon->unix_ext)
588 cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid); 592 rc = cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid);
589 else 593 else
590 cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid); 594 rc = cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid);
595 if (rc && cifs_sb->tcon->ipc) {
596 cFYI(1, ("ipc connection - fake read inode"));
597 inode->i_mode |= S_IFDIR;
598 inode->i_nlink = 2;
599 inode->i_op = &cifs_ipc_inode_ops;
600 inode->i_fop = &simple_dir_operations;
601 inode->i_uid = cifs_sb->mnt_uid;
602 inode->i_gid = cifs_sb->mnt_gid;
603 }
604
591 /* can not call macro FreeXid here since in a void func */ 605 /* can not call macro FreeXid here since in a void func */
592 _FreeXid(xid); 606 _FreeXid(xid);
593} 607}
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 0bcec0844bee..51ec681fe74a 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -169,7 +169,6 @@ cifs_buf_get(void)
169void 169void
170cifs_buf_release(void *buf_to_free) 170cifs_buf_release(void *buf_to_free)
171{ 171{
172
173 if (buf_to_free == NULL) { 172 if (buf_to_free == NULL) {
174 /* cFYI(1, ("Null buffer passed to cifs_buf_release"));*/ 173 /* cFYI(1, ("Null buffer passed to cifs_buf_release"));*/
175 return; 174 return;