diff options
| author | Steve French <sfrench@us.ibm.com> | 2007-09-28 18:28:55 -0400 |
|---|---|---|
| committer | Steve French <sfrench@us.ibm.com> | 2007-09-28 18:28:55 -0400 |
| commit | 7f8ed420f80c91176dfd27c8089f22cab5c9ba78 (patch) | |
| tree | bd3cea6554c3e59230c83fa7e9912740e178b00c | |
| parent | 407f61a2b482ab9a6d03549ab9513e4a823ae4a2 (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>
| -rw-r--r-- | fs/cifs/cifsglob.h | 2 | ||||
| -rw-r--r-- | fs/cifs/connect.c | 18 | ||||
| -rw-r--r-- | fs/cifs/dir.c | 2 | ||||
| -rw-r--r-- | fs/cifs/inode.c | 22 | ||||
| -rw-r--r-- | fs/cifs/misc.c | 1 |
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 | ||
| 578 | static const struct inode_operations cifs_ipc_inode_ops = { | ||
| 579 | .lookup = cifs_lookup, | ||
| 580 | }; | ||
| 581 | |||
| 578 | /* gets root inode */ | 582 | /* gets root inode */ |
| 579 | void cifs_read_inode(struct inode *inode) | 583 | void 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) | |||
| 169 | void | 169 | void |
| 170 | cifs_buf_release(void *buf_to_free) | 170 | cifs_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; |
