[CIFS] Fix mknod of block and chardev over SFU mounts
Signed-off-by: Steve French <sfrench@us.ibm.com>
This commit is contained in:
parent
c119b87d59
commit
86c96b4bb7
3 changed files with 62 additions and 13 deletions
|
@ -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 {
|
||||||
} __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:
|
||||||
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
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
/* 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;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue