Skip to content

Commit

Permalink
[CIFS] Fix mknod of block and chardev over SFU mounts
Browse files Browse the repository at this point in the history
Signed-off-by: Steve French <sfrench@us.ibm.com>
  • Loading branch information
Steve French committed Nov 19, 2005
1 parent c119b87 commit 86c96b4
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 13 deletions.
10 changes: 9 additions & 1 deletion fs/cifs/cifspdu.h
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,9 @@ typedef struct smb_com_logoff_andx_rsp {
__u16 ByteCount;
} __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 smb_hdr hdr; /* wct = 0 */
__u16 ByteCount; /* bcc = 0 */
Expand Down Expand Up @@ -2025,6 +2027,12 @@ typedef struct {
} __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 {
unsigned char name_len;
char name[1];
Expand Down
32 changes: 30 additions & 2 deletions fs/cifs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
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 xid;
Expand Down Expand Up @@ -368,7 +369,34 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev

if(!rc) {
/* 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);
d_drop(direntry);
}
Expand Down
33 changes: 23 additions & 10 deletions fs/cifs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
int oplock = FALSE;
__u16 netfid;
struct cifsTconInfo *pTcon = cifs_sb->tcon;
char buf[8];
char buf[24];
unsigned int bytes_read;
char * pbuf;

Expand All @@ -232,30 +232,43 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
/* Read header */
rc = CIFSSMBRead(xid, pTcon,
netfid,
8 /* length */, 0 /* offset */,
24 /* length */, 0 /* offset */,
&bytes_read, &pbuf);
if((rc == 0) && (bytes_read == 8)) {
if((rc == 0) && (bytes_read >= 8)) {
if(memcmp("IntxBLK", pbuf, 8) == 0) {
cFYI(1,("Block device"));
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) {
cFYI(1,("Char device"));
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) {
cFYI(1,("Symlink"));
inode->i_mode |= S_IFLNK;
}
} else {
inode->i_mode |= S_IFREG; /* file? */
rc = -EOPNOTSUPP;
}
} else {
inode->i_mode |= S_IFREG; /* then it is a file */
rc = -EOPNOTSUPP; /* or some unknown SFU type */
}

CIFSSMBClose(xid, pTcon, netfid);


/* inode->i_rdev = MKDEV(le64_to_cpu(DevMajor),
le64_to_cpu(DevMinor) & MINORMASK);*/
/* inode->i_mode |= S_IFBLK; */
}
return rc;

Expand Down

0 comments on commit 86c96b4

Please sign in to comment.