aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2005-11-18 23:25:31 -0500
committerSteve French <sfrench@us.ibm.com>2005-11-18 23:25:31 -0500
commit86c96b4bb70dac67d6815e09a0949427d439b280 (patch)
treef36ac16583ea9f935fcbed006a8edd99cf83852f
parentc119b87d596cdd99ac20095ae2ae90b525418605 (diff)
[CIFS] Fix mknod of block and chardev over SFU mounts
Signed-off-by: Steve French <sfrench@us.ibm.com>
-rw-r--r--fs/cifs/cifspdu.h10
-rw-r--r--fs/cifs/dir.c32
-rw-r--r--fs/cifs/inode.c33
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
606typedef union smb_com_tree_disconnect { /* as an altetnative can use flag on tree_connect PDU to effect disconnect *//* probably the simplest SMB PDU */ 606typedef 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
2030struct win_dev {
2031 unsigned char type[8]; /* IntxCHR or IntxBLK */
2032 __le64 major;
2033 __le64 minor;
2034} __attribute__((packed));
2035
2028struct gea { 2036struct 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
295int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t device_number) 295int 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