Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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



Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent c119b87d
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -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 */
@@ -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];
+30 −2
Original line number Diff line number Diff line
@@ -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;
@@ -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);
			}
+23 −10
Original line number Diff line number Diff line
@@ -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;

@@ -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;