Commit 86c96b4b authored by Steve French's avatar Steve French

[CIFS] Fix mknod of block and chardev over SFU mounts

Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent c119b87d
...@@ -603,7 +603,9 @@ typedef struct smb_com_logoff_andx_rsp { ...@@ -603,7 +603,9 @@ typedef struct smb_com_logoff_andx_rsp {
__u16 ByteCount; __u16 ByteCount;
} __attribute__((packed)) LOGOFF_ANDX_RSP; } __attribute__((packed)) LOGOFF_ANDX_RSP;
typedef union smb_com_tree_disconnect { /* as an altetnative can use flag on tree_connect PDU to effect disconnect *//* probably the simplest SMB PDU */ typedef union smb_com_tree_disconnect { /* as an altetnative can use flag on
tree_connect PDU to effect disconnect */
/* tdis is probably simplest SMB PDU */
struct { struct {
struct smb_hdr hdr; /* wct = 0 */ struct smb_hdr hdr; /* wct = 0 */
__u16 ByteCount; /* bcc = 0 */ __u16 ByteCount; /* bcc = 0 */
...@@ -2025,6 +2027,12 @@ typedef struct { ...@@ -2025,6 +2027,12 @@ typedef struct {
} __attribute__((packed)) FILE_BOTH_DIRECTORY_INFO; /* level 0x104 FF response data area */ } __attribute__((packed)) FILE_BOTH_DIRECTORY_INFO; /* level 0x104 FF response data area */
struct win_dev {
unsigned char type[8]; /* IntxCHR or IntxBLK */
__le64 major;
__le64 minor;
} __attribute__((packed));
struct gea { struct gea {
unsigned char name_len; unsigned char name_len;
char name[1]; char name[1];
......
...@@ -292,7 +292,8 @@ cifs_create_out: ...@@ -292,7 +292,8 @@ cifs_create_out:
return rc; return rc;
} }
int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t device_number) int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
dev_t device_number)
{ {
int rc = -EPERM; int rc = -EPERM;
int xid; int xid;
...@@ -368,7 +369,34 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev ...@@ -368,7 +369,34 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev
if(!rc) { if(!rc) {
/* BB Do not bother to decode buf since no /* BB Do not bother to decode buf since no
local inode yet to put timestamps in */ local inode yet to put timestamps in,
but we can reuse it safely */
int bytes_written;
struct win_dev *pdev;
pdev = (struct win_dev *)buf;
if(S_ISCHR(mode)) {
memcpy(pdev->type, "IntxCHR", 8);
pdev->major =
cpu_to_le64(MAJOR(device_number));
pdev->minor =
cpu_to_le64(MINOR(device_number));
rc = CIFSSMBWrite(xid, pTcon,
fileHandle,
sizeof(struct win_dev),
0, &bytes_written, (char *)pdev,
NULL, 0);
} else if(S_ISBLK(mode)) {
memcpy(pdev->type, "IntxBLK", 8);
pdev->major =
cpu_to_le64(MAJOR(device_number));
pdev->minor =
cpu_to_le64(MINOR(device_number));
rc = CIFSSMBWrite(xid, pTcon,
fileHandle,
sizeof(struct win_dev),
0, &bytes_written, (char *)pdev,
NULL, 0);
} /* else if(S_ISFIFO */
CIFSSMBClose(xid, pTcon, fileHandle); CIFSSMBClose(xid, pTcon, fileHandle);
d_drop(direntry); d_drop(direntry);
} }
......
...@@ -210,7 +210,7 @@ static int decode_sfu_inode(struct inode * inode, __u64 size, ...@@ -210,7 +210,7 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
int oplock = FALSE; int oplock = FALSE;
__u16 netfid; __u16 netfid;
struct cifsTconInfo *pTcon = cifs_sb->tcon; struct cifsTconInfo *pTcon = cifs_sb->tcon;
char buf[8]; char buf[24];
unsigned int bytes_read; unsigned int bytes_read;
char * pbuf; char * pbuf;
...@@ -232,30 +232,43 @@ static int decode_sfu_inode(struct inode * inode, __u64 size, ...@@ -232,30 +232,43 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
/* Read header */ /* Read header */
rc = CIFSSMBRead(xid, pTcon, rc = CIFSSMBRead(xid, pTcon,
netfid, netfid,
8 /* length */, 0 /* offset */, 24 /* length */, 0 /* offset */,
&bytes_read, &pbuf); &bytes_read, &pbuf);
if((rc == 0) && (bytes_read == 8)) { if((rc == 0) && (bytes_read >= 8)) {
if(memcmp("IntxBLK", pbuf, 8) == 0) { if(memcmp("IntxBLK", pbuf, 8) == 0) {
cFYI(1,("Block device")); cFYI(1,("Block device"));
inode->i_mode |= S_IFBLK; inode->i_mode |= S_IFBLK;
if(bytes_read == 24) {
/* we have enough to decode dev num */
__u64 mjr; /* major */
__u64 mnr; /* minor */
mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
inode->i_rdev = MKDEV(mjr, mnr);
}
} else if(memcmp("IntxCHR", pbuf, 8) == 0) { } else if(memcmp("IntxCHR", pbuf, 8) == 0) {
cFYI(1,("Char device")); cFYI(1,("Char device"));
inode->i_mode |= S_IFCHR; inode->i_mode |= S_IFCHR;
if(bytes_read == 24) {
/* we have enough to decode dev num */
__u64 mjr; /* major */
__u64 mnr; /* minor */
mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
inode->i_rdev = MKDEV(mjr, mnr);
}
} else if(memcmp("IntxLNK", pbuf, 7) == 0) { } else if(memcmp("IntxLNK", pbuf, 7) == 0) {
cFYI(1,("Symlink")); cFYI(1,("Symlink"));
inode->i_mode |= S_IFLNK; inode->i_mode |= S_IFLNK;
} } else {
inode->i_mode |= S_IFREG; /* file? */
rc = -EOPNOTSUPP;
}
} else { } else {
inode->i_mode |= S_IFREG; /* then it is a file */ inode->i_mode |= S_IFREG; /* then it is a file */
rc = -EOPNOTSUPP; /* or some unknown SFU type */ rc = -EOPNOTSUPP; /* or some unknown SFU type */
} }
CIFSSMBClose(xid, pTcon, netfid); CIFSSMBClose(xid, pTcon, netfid);
/* inode->i_rdev = MKDEV(le64_to_cpu(DevMajor),
le64_to_cpu(DevMinor) & MINORMASK);*/
/* inode->i_mode |= S_IFBLK; */
} }
return rc; return rc;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment