Exemplo n.º 1
0
static int
CIFSQueryMFSymLink(const int xid, struct cifs_tcon *tcon,
		   const unsigned char *searchName, char **symlinkinfo,
		   const struct nls_table *nls_codepage, int remap)
{
	int rc;
	int oplock = 0;
	__u16 netfid = 0;
	u8 *buf;
	char *pbuf;
	unsigned int bytes_read = 0;
	int buf_type = CIFS_NO_BUFFER;
	unsigned int link_len = 0;
	struct cifs_io_parms io_parms;
	FILE_ALL_INFO file_info;

	rc = CIFSSMBOpen(xid, tcon, searchName, FILE_OPEN, GENERIC_READ,
			 CREATE_NOT_DIR, &netfid, &oplock, &file_info,
			 nls_codepage, remap);
	if (rc != 0)
		return rc;

	if (file_info.EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) {
		CIFSSMBClose(xid, tcon, netfid);
		/* it's not a symlink */
		return -EINVAL;
	}

	buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;
	pbuf = buf;
	io_parms.netfid = netfid;
	io_parms.pid = current->tgid;
	io_parms.tcon = tcon;
	io_parms.offset = 0;
	io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;

	rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf, &buf_type);
	CIFSSMBClose(xid, tcon, netfid);
	if (rc != 0) {
		kfree(buf);
		return rc;
	}

	rc = CIFSParseMFSymlink(buf, bytes_read, &link_len, symlinkinfo);
	kfree(buf);
	if (rc != 0)
		return rc;

	return 0;
}
Exemplo n.º 2
0
int
cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
		      struct cifs_sb_info *cifs_sb, const unsigned char *path,
		      char *pbuf, unsigned int *pbytes_read)
{
	int rc;
	int oplock = 0;
	struct cifs_fid fid;
	struct cifs_open_parms oparms;
	struct cifs_io_parms io_parms;
	int buf_type = CIFS_NO_BUFFER;
	FILE_ALL_INFO file_info;

	oparms.tcon = tcon;
	oparms.cifs_sb = cifs_sb;
	oparms.desired_access = GENERIC_READ;
	oparms.create_options = CREATE_NOT_DIR;
	oparms.disposition = FILE_OPEN;
	oparms.path = path;
	oparms.fid = &fid;
	oparms.reconnect = false;

	rc = CIFS_open(xid, &oparms, &oplock, &file_info);
	if (rc)
		return rc;

	if (file_info.EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) {
		rc = -ENOENT;
		/* it's not a symlink */
		goto out;
	}

	io_parms.netfid = fid.netfid;
	io_parms.pid = current->tgid;
	io_parms.tcon = tcon;
	io_parms.offset = 0;
	io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;

	rc = CIFSSMBRead(xid, &io_parms, pbytes_read, &pbuf, &buf_type);
out:
	CIFSSMBClose(xid, tcon, fid.netfid);
	return rc;
}
Exemplo n.º 3
0
int
CIFSCheckMFSymlink(struct cifs_fattr *fattr,
		   const unsigned char *path,
		   struct cifs_sb_info *cifs_sb, int xid)
{
	int rc;
	int oplock = 0;
	__u16 netfid = 0;
	struct tcon_link *tlink;
	struct cifsTconInfo *pTcon;
	u8 *buf;
	char *pbuf;
	unsigned int bytes_read = 0;
	int buf_type = CIFS_NO_BUFFER;
	unsigned int link_len = 0;
	FILE_ALL_INFO file_info;

	if (!CIFSCouldBeMFSymlink(fattr))
		/* it's not a symlink */
		return 0;

	tlink = cifs_sb_tlink(cifs_sb);
	if (IS_ERR(tlink))
		return PTR_ERR(tlink);
	pTcon = tlink_tcon(tlink);

	rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ,
			 CREATE_NOT_DIR, &netfid, &oplock, &file_info,
			 cifs_sb->local_nls,
			 cifs_sb->mnt_cifs_flags &
				CIFS_MOUNT_MAP_SPECIAL_CHR);
	if (rc != 0)
		goto out;

	if (file_info.EndOfFile != CIFS_MF_SYMLINK_FILE_SIZE) {
		CIFSSMBClose(xid, pTcon, netfid);
		/* it's not a symlink */
		goto out;
	}

	buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
	if (!buf) {
		rc = -ENOMEM;
		goto out;
	}
	pbuf = buf;

	rc = CIFSSMBRead(xid, pTcon, netfid,
			 CIFS_MF_SYMLINK_FILE_SIZE /* length */,
			 0 /* offset */,
			 &bytes_read, &pbuf, &buf_type);
	CIFSSMBClose(xid, pTcon, netfid);
	if (rc != 0) {
		kfree(buf);
		goto out;
	}

	rc = CIFSParseMFSymlink(buf, bytes_read, &link_len, NULL);
	kfree(buf);
	if (rc == -EINVAL) {
		/* it's not a symlink */
		rc = 0;
		goto out;
	}

	if (rc != 0)
		goto out;

	/* it is a symlink */
	fattr->cf_eof = link_len;
	fattr->cf_mode &= ~S_IFMT;
	fattr->cf_mode |= S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO;
	fattr->cf_dtype = DT_LNK;
out:
	cifs_put_tlink(tlink);
	return rc;
}
Exemplo n.º 4
0
static int decode_sfu_inode(struct inode * inode, __u64 size,
			    const unsigned char *path,
			    struct cifs_sb_info *cifs_sb, int xid)
{
	int rc;
	int oplock = FALSE;
	__u16 netfid;
	struct cifsTconInfo *pTcon = cifs_sb->tcon;
	char buf[24];
	unsigned int bytes_read;
	char * pbuf;

	pbuf = buf;

	if(size == 0) {
		inode->i_mode |= S_IFIFO;
		return 0;
	} else if (size < 8) {
		return -EINVAL;	 /* EOPNOTSUPP? */
	}
		
	rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ,
			 CREATE_NOT_DIR, &netfid, &oplock, NULL,
			 cifs_sb->local_nls,
			 cifs_sb->mnt_cifs_flags &
				CIFS_MOUNT_MAP_SPECIAL_CHR);
	if (rc==0) {
		int buf_type = CIFS_NO_BUFFER;
			/* Read header */
		rc = CIFSSMBRead(xid, pTcon,
			         netfid,
				 24 /* length */, 0 /* offset */,
				 &bytes_read, &pbuf, &buf_type);
		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);
	}
	return rc;
	
}