diff options
author | Steve French <sfrench@us.ibm.com> | 2005-11-18 23:25:31 -0500 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2005-11-18 23:25:31 -0500 |
commit | 86c96b4bb70dac67d6815e09a0949427d439b280 (patch) | |
tree | f36ac16583ea9f935fcbed006a8edd99cf83852f /fs/cifs | |
parent | c119b87d596cdd99ac20095ae2ae90b525418605 (diff) |
[CIFS] Fix mknod of block and chardev over SFU mounts
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/cifspdu.h | 10 | ||||
-rw-r--r-- | fs/cifs/dir.c | 32 | ||||
-rw-r--r-- | fs/cifs/inode.c | 33 |
3 files changed, 62 insertions, 13 deletions
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 48a05b9df7eb..33e1859fd2f6 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h | |||
@@ -603,7 +603,9 @@ typedef struct smb_com_logoff_andx_rsp { | |||
603 | __u16 ByteCount; | 603 | __u16 ByteCount; |
604 | } __attribute__((packed)) LOGOFF_ANDX_RSP; | 604 | } __attribute__((packed)) LOGOFF_ANDX_RSP; |
605 | 605 | ||
606 | typedef union smb_com_tree_disconnect { /* as an altetnative can use flag on tree_connect PDU to effect disconnect *//* probably the simplest SMB PDU */ | 606 | typedef union smb_com_tree_disconnect { /* as an altetnative can use flag on |
607 | tree_connect PDU to effect disconnect */ | ||
608 | /* tdis is probably simplest SMB PDU */ | ||
607 | struct { | 609 | struct { |
608 | struct smb_hdr hdr; /* wct = 0 */ | 610 | struct smb_hdr hdr; /* wct = 0 */ |
609 | __u16 ByteCount; /* bcc = 0 */ | 611 | __u16 ByteCount; /* bcc = 0 */ |
@@ -2025,6 +2027,12 @@ typedef struct { | |||
2025 | } __attribute__((packed)) FILE_BOTH_DIRECTORY_INFO; /* level 0x104 FF response data area */ | 2027 | } __attribute__((packed)) FILE_BOTH_DIRECTORY_INFO; /* level 0x104 FF response data area */ |
2026 | 2028 | ||
2027 | 2029 | ||
2030 | struct win_dev { | ||
2031 | unsigned char type[8]; /* IntxCHR or IntxBLK */ | ||
2032 | __le64 major; | ||
2033 | __le64 minor; | ||
2034 | } __attribute__((packed)); | ||
2035 | |||
2028 | struct gea { | 2036 | struct gea { |
2029 | unsigned char name_len; | 2037 | unsigned char name_len; |
2030 | char name[1]; | 2038 | char name[1]; |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 8dfe717a332a..16b21522e8fe 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -292,7 +292,8 @@ cifs_create_out: | |||
292 | return rc; | 292 | return rc; |
293 | } | 293 | } |
294 | 294 | ||
295 | int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t device_number) | 295 | int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, |
296 | dev_t device_number) | ||
296 | { | 297 | { |
297 | int rc = -EPERM; | 298 | int rc = -EPERM; |
298 | int xid; | 299 | int xid; |
@@ -368,7 +369,34 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev | |||
368 | 369 | ||
369 | if(!rc) { | 370 | if(!rc) { |
370 | /* BB Do not bother to decode buf since no | 371 | /* BB Do not bother to decode buf since no |
371 | local inode yet to put timestamps in */ | 372 | local inode yet to put timestamps in, |
373 | but we can reuse it safely */ | ||
374 | int bytes_written; | ||
375 | struct win_dev *pdev; | ||
376 | pdev = (struct win_dev *)buf; | ||
377 | if(S_ISCHR(mode)) { | ||
378 | memcpy(pdev->type, "IntxCHR", 8); | ||
379 | pdev->major = | ||
380 | cpu_to_le64(MAJOR(device_number)); | ||
381 | pdev->minor = | ||
382 | cpu_to_le64(MINOR(device_number)); | ||
383 | rc = CIFSSMBWrite(xid, pTcon, | ||
384 | fileHandle, | ||
385 | sizeof(struct win_dev), | ||
386 | 0, &bytes_written, (char *)pdev, | ||
387 | NULL, 0); | ||
388 | } else if(S_ISBLK(mode)) { | ||
389 | memcpy(pdev->type, "IntxBLK", 8); | ||
390 | pdev->major = | ||
391 | cpu_to_le64(MAJOR(device_number)); | ||
392 | pdev->minor = | ||
393 | cpu_to_le64(MINOR(device_number)); | ||
394 | rc = CIFSSMBWrite(xid, pTcon, | ||
395 | fileHandle, | ||
396 | sizeof(struct win_dev), | ||
397 | 0, &bytes_written, (char *)pdev, | ||
398 | NULL, 0); | ||
399 | } /* else if(S_ISFIFO */ | ||
372 | CIFSSMBClose(xid, pTcon, fileHandle); | 400 | CIFSSMBClose(xid, pTcon, fileHandle); |
373 | d_drop(direntry); | 401 | d_drop(direntry); |
374 | } | 402 | } |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index f0586c0d7bdb..d7b85dfb0df3 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -210,7 +210,7 @@ static int decode_sfu_inode(struct inode * inode, __u64 size, | |||
210 | int oplock = FALSE; | 210 | int oplock = FALSE; |
211 | __u16 netfid; | 211 | __u16 netfid; |
212 | struct cifsTconInfo *pTcon = cifs_sb->tcon; | 212 | struct cifsTconInfo *pTcon = cifs_sb->tcon; |
213 | char buf[8]; | 213 | char buf[24]; |
214 | unsigned int bytes_read; | 214 | unsigned int bytes_read; |
215 | char * pbuf; | 215 | char * pbuf; |
216 | 216 | ||
@@ -232,30 +232,43 @@ static int decode_sfu_inode(struct inode * inode, __u64 size, | |||
232 | /* Read header */ | 232 | /* Read header */ |
233 | rc = CIFSSMBRead(xid, pTcon, | 233 | rc = CIFSSMBRead(xid, pTcon, |
234 | netfid, | 234 | netfid, |
235 | 8 /* length */, 0 /* offset */, | 235 | 24 /* length */, 0 /* offset */, |
236 | &bytes_read, &pbuf); | 236 | &bytes_read, &pbuf); |
237 | if((rc == 0) && (bytes_read == 8)) { | 237 | if((rc == 0) && (bytes_read >= 8)) { |
238 | if(memcmp("IntxBLK", pbuf, 8) == 0) { | 238 | if(memcmp("IntxBLK", pbuf, 8) == 0) { |
239 | cFYI(1,("Block device")); | 239 | cFYI(1,("Block device")); |
240 | inode->i_mode |= S_IFBLK; | 240 | inode->i_mode |= S_IFBLK; |
241 | if(bytes_read == 24) { | ||
242 | /* we have enough to decode dev num */ | ||
243 | __u64 mjr; /* major */ | ||
244 | __u64 mnr; /* minor */ | ||
245 | mjr = le64_to_cpu(*(__le64 *)(pbuf+8)); | ||
246 | mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); | ||
247 | inode->i_rdev = MKDEV(mjr, mnr); | ||
248 | } | ||
241 | } else if(memcmp("IntxCHR", pbuf, 8) == 0) { | 249 | } else if(memcmp("IntxCHR", pbuf, 8) == 0) { |
242 | cFYI(1,("Char device")); | 250 | cFYI(1,("Char device")); |
243 | inode->i_mode |= S_IFCHR; | 251 | inode->i_mode |= S_IFCHR; |
252 | if(bytes_read == 24) { | ||
253 | /* we have enough to decode dev num */ | ||
254 | __u64 mjr; /* major */ | ||
255 | __u64 mnr; /* minor */ | ||
256 | mjr = le64_to_cpu(*(__le64 *)(pbuf+8)); | ||
257 | mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); | ||
258 | inode->i_rdev = MKDEV(mjr, mnr); | ||
259 | } | ||
244 | } else if(memcmp("IntxLNK", pbuf, 7) == 0) { | 260 | } else if(memcmp("IntxLNK", pbuf, 7) == 0) { |
245 | cFYI(1,("Symlink")); | 261 | cFYI(1,("Symlink")); |
246 | inode->i_mode |= S_IFLNK; | 262 | inode->i_mode |= S_IFLNK; |
247 | } | 263 | } else { |
264 | inode->i_mode |= S_IFREG; /* file? */ | ||
265 | rc = -EOPNOTSUPP; | ||
266 | } | ||
248 | } else { | 267 | } else { |
249 | inode->i_mode |= S_IFREG; /* then it is a file */ | 268 | inode->i_mode |= S_IFREG; /* then it is a file */ |
250 | rc = -EOPNOTSUPP; /* or some unknown SFU type */ | 269 | rc = -EOPNOTSUPP; /* or some unknown SFU type */ |
251 | } | 270 | } |
252 | |||
253 | CIFSSMBClose(xid, pTcon, netfid); | 271 | CIFSSMBClose(xid, pTcon, netfid); |
254 | |||
255 | |||
256 | /* inode->i_rdev = MKDEV(le64_to_cpu(DevMajor), | ||
257 | le64_to_cpu(DevMinor) & MINORMASK);*/ | ||
258 | /* inode->i_mode |= S_IFBLK; */ | ||
259 | } | 272 | } |
260 | return rc; | 273 | return rc; |
261 | 274 | ||