diff options
-rw-r--r-- | fs/cifs/CHANGES | 9 | ||||
-rw-r--r-- | fs/cifs/cifsfs.h | 6 | ||||
-rw-r--r-- | fs/cifs/cifspdu.h | 69 | ||||
-rw-r--r-- | fs/cifs/cifsproto.h | 4 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 86 | ||||
-rw-r--r-- | fs/cifs/ioctl.c | 52 |
6 files changed, 212 insertions, 14 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 5316c8dd6bff..7fd02697b12e 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
@@ -1,7 +1,14 @@ | |||
1 | Version 1.31 | 1 | Version 1.32 |
2 | ------------ | 2 | ------------ |
3 | Fix oops in ls when Transact2 FindFirst (or FindNext) returns more than one | 3 | Fix oops in ls when Transact2 FindFirst (or FindNext) returns more than one |
4 | transact response for an SMB request and search entry split across two frames. | 4 | transact response for an SMB request and search entry split across two frames. |
5 | Add support for lsattr (getting ext2/ext3/reiserfs attr flags from the server) | ||
6 | as new protocol extensions. Do not send Get/Set calls for POSIX ACLs | ||
7 | unless server explicitly claims to support them in CIFS Unix extensions | ||
8 | POSIX ACL capability bit. | ||
9 | |||
10 | Version 1.31 | ||
11 | ------------ | ||
5 | Fix updates of DOS attributes and time fields so that files on NT4 servers | 12 | Fix updates of DOS attributes and time fields so that files on NT4 servers |
6 | do not get marked delete on close. Display sizes of cifs buffer pools in | 13 | do not get marked delete on close. Display sizes of cifs buffer pools in |
7 | cifs stats. Fix oops in unmount when cifsd thread being killed by | 14 | cifs stats. Fix oops in unmount when cifsd thread being killed by |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 451f18af3206..e0e46f4bff97 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
@@ -91,8 +91,10 @@ extern int cifs_symlink(struct inode *inode, struct dentry *direntry, | |||
91 | const char *symname); | 91 | const char *symname); |
92 | extern int cifs_removexattr(struct dentry *, const char *); | 92 | extern int cifs_removexattr(struct dentry *, const char *); |
93 | extern int cifs_setxattr(struct dentry *, const char *, const void *, | 93 | extern int cifs_setxattr(struct dentry *, const char *, const void *, |
94 | size_t, int); | 94 | size_t, int); |
95 | extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); | 95 | extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); |
96 | extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); | 96 | extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); |
97 | #define CIFS_VERSION "1.31" | 97 | extern int cifs_ioctl (struct inode * inode, struct file * filep, |
98 | unsigned int command, unsigned long arg); | ||
99 | #define CIFS_VERSION "1.32" | ||
98 | #endif /* _CIFSFS_H */ | 100 | #endif /* _CIFSFS_H */ |
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index bcd4a6136f08..085109d2b55e 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h | |||
@@ -762,6 +762,16 @@ typedef struct smb_com_lock_req { | |||
762 | LOCKING_ANDX_RANGE Locks[1]; | 762 | LOCKING_ANDX_RANGE Locks[1]; |
763 | } LOCK_REQ; | 763 | } LOCK_REQ; |
764 | 764 | ||
765 | |||
766 | typedef struct cifs_posix_lock { | ||
767 | __le16 lock_type; /* 0 = Read, 1 = Write, 2 = Unlock */ | ||
768 | __le16 lock_flags; /* 1 = Wait (only valid for setlock) */ | ||
769 | __le32 pid; | ||
770 | __le64 start; | ||
771 | __le64 length; | ||
772 | /* BB what about additional owner info to identify network client */ | ||
773 | } CIFS_POSIX_LOCK; | ||
774 | |||
765 | typedef struct smb_com_lock_rsp { | 775 | typedef struct smb_com_lock_rsp { |
766 | struct smb_hdr hdr; /* wct = 2 */ | 776 | struct smb_hdr hdr; /* wct = 2 */ |
767 | __u8 AndXCommand; | 777 | __u8 AndXCommand; |
@@ -1098,6 +1108,8 @@ struct smb_t2_rsp { | |||
1098 | #define SMB_QUERY_POSIX_ACL 0x204 | 1108 | #define SMB_QUERY_POSIX_ACL 0x204 |
1099 | #define SMB_QUERY_XATTR 0x205 | 1109 | #define SMB_QUERY_XATTR 0x205 |
1100 | #define SMB_QUERY_ATTR_FLAGS 0x206 /* append,immutable etc. */ | 1110 | #define SMB_QUERY_ATTR_FLAGS 0x206 /* append,immutable etc. */ |
1111 | #define SMB_QUERY_POSIX_PERMISSION 0x207 | ||
1112 | #define SMB_QUERY_POSIX_LOCK 0x208 | ||
1101 | #define SMB_QUERY_FILE_INTERNAL_INFO 0x3ee | 1113 | #define SMB_QUERY_FILE_INTERNAL_INFO 0x3ee |
1102 | #define SMB_QUERY_FILE_ACCESS_INFO 0x3f0 | 1114 | #define SMB_QUERY_FILE_ACCESS_INFO 0x3f0 |
1103 | #define SMB_QUERY_FILE_NAME_INFO2 0x3f1 /* 0x30 bytes */ | 1115 | #define SMB_QUERY_FILE_NAME_INFO2 0x3f1 /* 0x30 bytes */ |
@@ -1116,6 +1128,7 @@ struct smb_t2_rsp { | |||
1116 | #define SMB_SET_POSIX_ACL 0x204 | 1128 | #define SMB_SET_POSIX_ACL 0x204 |
1117 | #define SMB_SET_XATTR 0x205 | 1129 | #define SMB_SET_XATTR 0x205 |
1118 | #define SMB_SET_ATTR_FLAGS 0x206 /* append, immutable etc. */ | 1130 | #define SMB_SET_ATTR_FLAGS 0x206 /* append, immutable etc. */ |
1131 | #define SMB_SET_POSIX_LOCK 0x208 | ||
1119 | #define SMB_SET_FILE_BASIC_INFO2 0x3ec | 1132 | #define SMB_SET_FILE_BASIC_INFO2 0x3ec |
1120 | #define SMB_SET_FILE_RENAME_INFORMATION 0x3f2 /* BB check if qpathinfo level too */ | 1133 | #define SMB_SET_FILE_RENAME_INFORMATION 0x3f2 /* BB check if qpathinfo level too */ |
1121 | #define SMB_FILE_ALL_INFO2 0x3fa | 1134 | #define SMB_FILE_ALL_INFO2 0x3fa |
@@ -1237,9 +1250,27 @@ struct smb_com_transaction2_sfi_rsp { | |||
1237 | struct smb_hdr hdr; /* wct = 10 + SetupCount */ | 1250 | struct smb_hdr hdr; /* wct = 10 + SetupCount */ |
1238 | struct trans2_resp t2; | 1251 | struct trans2_resp t2; |
1239 | __u16 ByteCount; | 1252 | __u16 ByteCount; |
1240 | __u16 Reserved2; /* parameter word reserved - present for infolevels > 100 */ | 1253 | __u16 Reserved2; /* parameter word reserved - |
1254 | present for infolevels > 100 */ | ||
1255 | }; | ||
1256 | |||
1257 | struct smb_t2_qfi_req { | ||
1258 | struct smb_hdr hdr; | ||
1259 | struct trans2_req t2; | ||
1260 | __u8 Pad; | ||
1261 | __u16 Pad1; | ||
1262 | __u16 Fid; | ||
1263 | __le16 InformationLevel; | ||
1264 | __u16 Pad2; | ||
1241 | }; | 1265 | }; |
1242 | 1266 | ||
1267 | struct smb_t2_qfi_rsp { | ||
1268 | struct smb_hdr hdr; /* wct = 10 + SetupCount */ | ||
1269 | struct trans2_resp t2; | ||
1270 | __u16 ByteCount; | ||
1271 | __u16 Reserved2; /* parameter word reserved - | ||
1272 | present for infolevels > 100 */ | ||
1273 | }; | ||
1243 | 1274 | ||
1244 | /* | 1275 | /* |
1245 | * Flags on T2 FINDFIRST and FINDNEXT | 1276 | * Flags on T2 FINDFIRST and FINDNEXT |
@@ -1524,8 +1555,9 @@ typedef struct { | |||
1524 | } FILE_SYSTEM_UNIX_INFO; /* Unix extensions info, level 0x200 */ | 1555 | } FILE_SYSTEM_UNIX_INFO; /* Unix extensions info, level 0x200 */ |
1525 | /* Linux/Unix extensions capability flags */ | 1556 | /* Linux/Unix extensions capability flags */ |
1526 | #define CIFS_UNIX_FCNTL_CAP 0x00000001 /* support for fcntl locks */ | 1557 | #define CIFS_UNIX_FCNTL_CAP 0x00000001 /* support for fcntl locks */ |
1527 | #define CIFS_UNIX_POSIX_ACL_CAP 0x00000002 | 1558 | #define CIFS_UNIX_POSIX_ACL_CAP 0x00000002 /* support getfacl/setfacl */ |
1528 | #define CIFS_UNIX_XATTR_CAP 0x00000004 /*support for new namespace*/ | 1559 | #define CIFS_UNIX_XATTR_CAP 0x00000004 /* support new namespace */ |
1560 | #define CIFS_UNIX_EXTATTR_CAP 0x00000008 /* support chattr/chflag */ | ||
1529 | 1561 | ||
1530 | typedef struct { | 1562 | typedef struct { |
1531 | /* For undefined recommended transfer size return -1 in that field */ | 1563 | /* For undefined recommended transfer size return -1 in that field */ |
@@ -1971,14 +2003,39 @@ struct xsymlink { | |||
1971 | char path[1024]; | 2003 | char path[1024]; |
1972 | }; | 2004 | }; |
1973 | 2005 | ||
1974 | typedef struct { | 2006 | typedef struct file_xattr_info { |
1975 | /* BB do we need another field for flags? BB */ | 2007 | /* BB do we need another field for flags? BB */ |
1976 | __u32 xattr_name_len; | 2008 | __u32 xattr_name_len; |
1977 | __u32 xattr_value_len; | 2009 | __u32 xattr_value_len; |
1978 | char xattr_name[0]; | 2010 | char xattr_name[0]; |
1979 | /* followed by xattr_value[xattr_value_len], no pad */ | 2011 | /* followed by xattr_value[xattr_value_len], no pad */ |
1980 | } FILE_XATTR_INFO; /* extended attribute, info level 205 */ | 2012 | } FILE_XATTR_INFO; /* extended attribute, info level 0x205 */ |
1981 | 2013 | ||
2014 | |||
2015 | /* flags for chattr command */ | ||
2016 | #define EXT_SECURE_DELETE 0x00000001 /* EXT3_SECRM_FL */ | ||
2017 | #define EXT_ENABLE_UNDELETE 0x00000002 /* EXT3_UNRM_FL */ | ||
2018 | /* Reserved for compress file 0x4 */ | ||
2019 | #define EXT_SYNCHRONOUS 0x00000008 /* EXT3_SYNC_FL */ | ||
2020 | #define EXT_IMMUTABLE_FL 0x00000010 /* EXT3_IMMUTABLE_FL */ | ||
2021 | #define EXT_OPEN_APPEND_ONLY 0x00000020 /* EXT3_APPEND_FL */ | ||
2022 | #define EXT_DO_NOT_BACKUP 0x00000040 /* EXT3_NODUMP_FL */ | ||
2023 | #define EXT_NO_UPDATE_ATIME 0x00000080 /* EXT3_NOATIME_FL */ | ||
2024 | /* 0x100 through 0x800 reserved for compression flags and are GET-ONLY */ | ||
2025 | #define EXT_HASH_TREE_INDEXED_DIR 0x00001000 /* GET-ONLY EXT3_INDEX_FL */ | ||
2026 | /* 0x2000 reserved for IMAGIC_FL */ | ||
2027 | #define EXT_JOURNAL_THIS_FILE 0x00004000 /* GET-ONLY EXT3_JOURNAL_DATA_FL */ | ||
2028 | /* 0x8000 reserved for EXT3_NOTAIL_FL */ | ||
2029 | #define EXT_SYNCHRONOUS_DIR 0x00010000 /* EXT3_DIRSYNC_FL */ | ||
2030 | #define EXT_TOPDIR 0x00020000 /* EXT3_TOPDIR_FL */ | ||
2031 | |||
2032 | #define EXT_SET_MASK 0x000300FF | ||
2033 | #define EXT_GET_MASK 0x0003DFFF | ||
2034 | |||
2035 | typedef struct file_chattr_info { | ||
2036 | __le64 mask; /* list of all possible attribute bits */ | ||
2037 | __le64 mode; /* list of actual attribute bits on this inode */ | ||
2038 | } FILE_CHATTR_INFO; /* ext attributes (chattr, chflags) level 0x206 */ | ||
1982 | 2039 | ||
1983 | #endif | 2040 | #endif |
1984 | 2041 | ||
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 787eef4d86d3..82ae59d7cf9d 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -264,6 +264,8 @@ extern int CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon, | |||
264 | const unsigned char *fileName, | 264 | const unsigned char *fileName, |
265 | const char *local_acl, const int buflen, const int acl_type, | 265 | const char *local_acl, const int buflen, const int acl_type, |
266 | const struct nls_table *nls_codepage); | 266 | const struct nls_table *nls_codepage); |
267 | int cifs_ioctl (struct inode * inode, struct file * filep, | 267 | extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon, |
268 | const int netfid, __u64 * pExtAttrBits, __u64 *pMask); | ||
269 | extern int cifs_ioctl (struct inode * inode, struct file * filep, | ||
268 | unsigned int command, unsigned long arg); | 270 | unsigned int command, unsigned long arg); |
269 | #endif /* _CIFSPROTO_H */ | 271 | #endif /* _CIFSPROTO_H */ |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index df6a619a6821..36d3c128a58b 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -2072,7 +2072,91 @@ setACLerrorExit: | |||
2072 | return rc; | 2072 | return rc; |
2073 | } | 2073 | } |
2074 | 2074 | ||
2075 | #endif | 2075 | /* BB fix tabs in this function FIXME BB */ |
2076 | int | ||
2077 | CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon, | ||
2078 | const int netfid, __u64 * pExtAttrBits, __u64 *pMask) | ||
2079 | { | ||
2080 | int rc = 0; | ||
2081 | struct smb_t2_qfi_req *pSMB = NULL; | ||
2082 | struct smb_t2_qfi_rsp *pSMBr = NULL; | ||
2083 | int bytes_returned; | ||
2084 | __u16 params, byte_count; | ||
2085 | |||
2086 | cFYI(1,("In GetExtAttr")); | ||
2087 | if(tcon == NULL) | ||
2088 | return -ENODEV; | ||
2089 | |||
2090 | GetExtAttrRetry: | ||
2091 | rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, | ||
2092 | (void **) &pSMBr); | ||
2093 | if (rc) | ||
2094 | return rc; | ||
2095 | |||
2096 | params = 2 /* level */ +2 /* fid */ + 2 /* rsrvd */; | ||
2097 | pSMB->t2.TotalDataCount = 0; | ||
2098 | pSMB->t2.MaxParameterCount = cpu_to_le16(2); | ||
2099 | /* BB find exact max data count below from sess structure BB */ | ||
2100 | pSMB->t2.MaxDataCount = cpu_to_le16(4000); | ||
2101 | pSMB->t2.MaxSetupCount = 0; | ||
2102 | pSMB->t2.Reserved = 0; | ||
2103 | pSMB->t2.Flags = 0; | ||
2104 | pSMB->t2.Timeout = 0; | ||
2105 | pSMB->t2.Reserved2 = 0; | ||
2106 | pSMB->t2.ParameterOffset = cpu_to_le16(offsetof( | ||
2107 | struct smb_com_transaction2_qpi_req ,InformationLevel) - 4); | ||
2108 | pSMB->t2.DataCount = 0; | ||
2109 | pSMB->t2.DataOffset = 0; | ||
2110 | pSMB->t2.SetupCount = 1; | ||
2111 | pSMB->t2.Reserved3 = 0; | ||
2112 | pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); | ||
2113 | byte_count = params + 3 /* pad */ ; | ||
2114 | pSMB->t2.TotalParameterCount = cpu_to_le16(params); | ||
2115 | pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount; | ||
2116 | pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS); | ||
2117 | pSMB->Pad1 = 0; | ||
2118 | pSMB->Pad2 = 0; | ||
2119 | pSMB->Fid = netfid; | ||
2120 | pSMB->hdr.smb_buf_length += byte_count; | ||
2121 | pSMB->t2.ByteCount = cpu_to_le16(byte_count); | ||
2122 | |||
2123 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, | ||
2124 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | ||
2125 | if (rc) { | ||
2126 | cFYI(1, ("error %d in GetExtAttr", rc)); | ||
2127 | } else { | ||
2128 | /* decode response */ | ||
2129 | rc = validate_t2((struct smb_t2_rsp *)pSMBr); | ||
2130 | if (rc || (pSMBr->ByteCount < 2)) | ||
2131 | /* BB also check enough total bytes returned */ | ||
2132 | /* If rc should we check for EOPNOSUPP and | ||
2133 | disable the srvino flag? or in caller? */ | ||
2134 | rc = -EIO; /* bad smb */ | ||
2135 | else { | ||
2136 | __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); | ||
2137 | __u16 count = le16_to_cpu(pSMBr->t2.DataCount); | ||
2138 | struct file_chattr_info * pfinfo; | ||
2139 | /* BB Do we need a cast or hash here ? */ | ||
2140 | if(count != 16) { | ||
2141 | cFYI(1, ("Illegal size ret in GetExtAttr")); | ||
2142 | rc = -EIO; | ||
2143 | goto GetExtAttrOut; | ||
2144 | } | ||
2145 | pfinfo = (struct file_chattr_info *) | ||
2146 | (data_offset + (char *) &pSMBr->hdr.Protocol); | ||
2147 | *pExtAttrBits = le64_to_cpu(pfinfo->mode); | ||
2148 | *pMask = le64_to_cpu(pfinfo->mask); | ||
2149 | } | ||
2150 | } | ||
2151 | GetExtAttrOut: | ||
2152 | cifs_buf_release(pSMB); | ||
2153 | if (rc == -EAGAIN) | ||
2154 | goto GetExtAttrRetry; | ||
2155 | return rc; | ||
2156 | } | ||
2157 | |||
2158 | |||
2159 | #endif /* CONFIG_POSIX */ | ||
2076 | 2160 | ||
2077 | int | 2161 | int |
2078 | CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, | 2162 | CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, |
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c index b4b8e201d428..7b84b2bb8c4a 100644 --- a/fs/cifs/ioctl.c +++ b/fs/cifs/ioctl.c | |||
@@ -20,6 +20,7 @@ | |||
20 | * along with this library; if not, write to the Free Software | 20 | * along with this library; if not, write to the Free Software |
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
22 | */ | 22 | */ |
23 | |||
23 | #include <linux/fs.h> | 24 | #include <linux/fs.h> |
24 | #include <linux/ext2_fs.h> | 25 | #include <linux/ext2_fs.h> |
25 | #include "cifspdu.h" | 26 | #include "cifspdu.h" |
@@ -32,18 +33,63 @@ int cifs_ioctl (struct inode * inode, struct file * filep, | |||
32 | { | 33 | { |
33 | int rc = -ENOTTY; /* strange error - but the precedent */ | 34 | int rc = -ENOTTY; /* strange error - but the precedent */ |
34 | #ifdef CONFIG_CIFS_POSIX | 35 | #ifdef CONFIG_CIFS_POSIX |
36 | __u64 ExtAttrBits = 0; | ||
37 | __u64 ExtAttrMask = 0; | ||
38 | __u64 caps; | ||
39 | #endif /* CONFIG_CIFS_POSIX */ | ||
40 | int xid; | ||
41 | struct cifs_sb_info *cifs_sb; | ||
42 | struct cifsTconInfo *tcon; | ||
43 | struct cifsFileInfo *pSMBFile = | ||
44 | (struct cifsFileInfo *)filep->private_data; | ||
45 | |||
46 | xid = GetXid(); | ||
47 | |||
48 | cifs_sb = CIFS_SB(inode->i_sb); | ||
49 | tcon = cifs_sb->tcon; | ||
50 | if (pSMBFile == NULL) | ||
51 | goto cifs_ioctl_out; | ||
52 | |||
53 | #ifdef CONFIG_CIFS_POSIX | ||
54 | if(tcon) | ||
55 | caps = le64_to_cpu(tcon->fsUnixInfo.Capability); | ||
56 | else { | ||
57 | rc = -EIO; | ||
58 | goto cifs_ioctl_out; | ||
59 | } | ||
60 | |||
35 | cFYI(1,("ioctl file %p cmd %u arg %lu",filep,command,arg)); | 61 | cFYI(1,("ioctl file %p cmd %u arg %lu",filep,command,arg)); |
36 | switch(command) { | 62 | switch(command) { |
37 | case EXT2_IOC_GETFLAGS: | 63 | case EXT2_IOC_GETFLAGS: |
38 | cFYI(1,("get flags not implemented yet")); | 64 | if(CIFS_UNIX_EXTATTR_CAP & caps) { |
39 | return -EOPNOTSUPP; | 65 | rc = CIFSGetExtAttr(xid, tcon, pSMBFile->netfid, |
66 | &ExtAttrBits, &ExtAttrMask); | ||
67 | if(rc == 0) | ||
68 | rc = put_user(ExtAttrBits & | ||
69 | EXT2_FL_USER_VISIBLE, | ||
70 | (int __user *)arg); | ||
71 | } | ||
72 | break; | ||
73 | |||
40 | case EXT2_IOC_SETFLAGS: | 74 | case EXT2_IOC_SETFLAGS: |
75 | if(CIFS_UNIX_EXTATTR_CAP & caps) { | ||
76 | if(get_user(ExtAttrBits,(int __user *)arg)) { | ||
77 | rc = -EFAULT; | ||
78 | goto cifs_ioctl_out; | ||
79 | } | ||
80 | /* rc = CIFSGetExtAttr(xid, tcon, pSMBFile->netfid, | ||
81 | extAttrBits, &ExtAttrMask);*/ | ||
82 | |||
83 | } | ||
41 | cFYI(1,("set flags not implemented yet")); | 84 | cFYI(1,("set flags not implemented yet")); |
42 | return -EOPNOTSUPP; | 85 | break; |
43 | default: | 86 | default: |
44 | cFYI(1,("unsupported ioctl")); | 87 | cFYI(1,("unsupported ioctl")); |
45 | return rc; | 88 | return rc; |
46 | } | 89 | } |
47 | #endif /* CONFIG_CIFS_POSIX */ | 90 | #endif /* CONFIG_CIFS_POSIX */ |
91 | |||
92 | cifs_ioctl_out: | ||
93 | FreeXid(xid); | ||
48 | return rc; | 94 | return rc; |
49 | } | 95 | } |