cifs: Add create MFSymlinks to protocol ops struct
Add a new protocol ops function create_mf_symlink and have create_mf_symlink() use it. This patchset moves the MFSymlink operations completely to the ops structure so that we only use the right protocol versions when querying or creating MFSymlinks. Signed-off-by: Sachin Prabhu <sprabhu@redhat.com> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <smfrench@gmail.com>
This commit is contained in:
		
					parent
					
						
							
								8205d1bb31
							
						
					
				
			
			
				commit
				
					
						cbb0aba6ff
					
				
			
		
					 4 changed files with 54 additions and 42 deletions
				
			
		|  | @ -373,6 +373,9 @@ struct smb_version_operations { | |||
| 	int (*query_mf_symlink)(unsigned int, struct cifs_tcon *, | ||||
| 				struct cifs_sb_info *, const unsigned char *, | ||||
| 				char *, unsigned int *); | ||||
| 	int (*create_mf_symlink)(unsigned int, struct cifs_tcon *, | ||||
| 				 struct cifs_sb_info *, const unsigned char *, | ||||
| 				 char *, unsigned int *); | ||||
| 	/* if we can do cache read operations */ | ||||
| 	bool (*is_read_op)(__u32); | ||||
| 	/* set oplock level for the inode */ | ||||
|  |  | |||
|  | @ -500,4 +500,8 @@ 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 cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, | ||||
| 			   struct cifs_sb_info *cifs_sb, | ||||
| 			   const unsigned char *path, char *pbuf, | ||||
| 			   unsigned int *pbytes_written); | ||||
| #endif			/* _CIFSPROTO_H */ | ||||
|  |  | |||
|  | @ -180,59 +180,31 @@ format_mf_symlink(u8 *buf, unsigned int buf_len, const char *link_str) | |||
| 
 | ||||
| static int | ||||
| create_mf_symlink(const unsigned int xid, struct cifs_tcon *tcon, | ||||
| 		    const char *fromName, const char *toName, | ||||
| 		    struct cifs_sb_info *cifs_sb) | ||||
| 		  struct cifs_sb_info *cifs_sb, const char *fromName, | ||||
| 		  const char *toName) | ||||
| { | ||||
| 	int rc; | ||||
| 	int oplock = 0; | ||||
| 	int remap; | ||||
| 	int create_options = CREATE_NOT_DIR; | ||||
| 	__u16 netfid = 0; | ||||
| 	u8 *buf; | ||||
| 	unsigned int bytes_written = 0; | ||||
| 	struct cifs_io_parms io_parms; | ||||
| 	struct nls_table *nls_codepage; | ||||
| 
 | ||||
| 	nls_codepage = cifs_sb->local_nls; | ||||
| 	remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR; | ||||
| 
 | ||||
| 	buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL); | ||||
| 	if (!buf) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	rc = format_mf_symlink(buf, CIFS_MF_SYMLINK_FILE_SIZE, toName); | ||||
| 	if (rc != 0) { | ||||
| 		kfree(buf); | ||||
| 		return rc; | ||||
| 	} | ||||
| 	if (rc) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	if (backup_cred(cifs_sb)) | ||||
| 		create_options |= CREATE_OPEN_BACKUP_INTENT; | ||||
| 
 | ||||
| 	rc = CIFSSMBOpen(xid, tcon, fromName, FILE_CREATE, GENERIC_WRITE, | ||||
| 			 create_options, &netfid, &oplock, NULL, | ||||
| 			 nls_codepage, remap); | ||||
| 	if (rc != 0) { | ||||
| 		kfree(buf); | ||||
| 		return rc; | ||||
| 	} | ||||
| 
 | ||||
| 	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 = CIFSSMBWrite(xid, &io_parms, &bytes_written, buf, NULL, 0); | ||||
| 	CIFSSMBClose(xid, tcon, netfid); | ||||
| 	kfree(buf); | ||||
| 	if (rc != 0) | ||||
| 		return rc; | ||||
| 	rc = tcon->ses->server->ops->create_mf_symlink(xid, tcon, cifs_sb, | ||||
| 					fromName, buf, &bytes_written); | ||||
| 	if (rc) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	if (bytes_written != CIFS_MF_SYMLINK_FILE_SIZE) | ||||
| 		return -EIO; | ||||
| 
 | ||||
| 	return 0; | ||||
| 		rc = -EIO; | ||||
| out: | ||||
| 	kfree(buf); | ||||
| 	return rc; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
|  | @ -319,6 +291,39 @@ out: | |||
| 	return rc; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, | ||||
| 		       struct cifs_sb_info *cifs_sb, const unsigned char *path, | ||||
| 		       char *pbuf, unsigned int *pbytes_written) | ||||
| { | ||||
| 	int rc; | ||||
| 	int oplock = 0; | ||||
| 	__u16 netfid = 0; | ||||
| 	struct cifs_io_parms io_parms; | ||||
| 	int create_options = CREATE_NOT_DIR; | ||||
| 
 | ||||
| 	if (backup_cred(cifs_sb)) | ||||
| 		create_options |= CREATE_OPEN_BACKUP_INTENT; | ||||
| 
 | ||||
| 	rc = CIFSSMBOpen(xid, tcon, path, FILE_CREATE, GENERIC_WRITE, | ||||
| 			 create_options, &netfid, &oplock, NULL, | ||||
| 			 cifs_sb->local_nls, | ||||
| 			 cifs_sb->mnt_cifs_flags & | ||||
| 				CIFS_MOUNT_MAP_SPECIAL_CHR); | ||||
| 	if (rc) | ||||
| 		return rc; | ||||
| 
 | ||||
| 	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 = CIFSSMBWrite(xid, &io_parms, pbytes_written, pbuf, NULL, 0); | ||||
| 	CIFSSMBClose(xid, tcon, netfid); | ||||
| 	return rc; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, | ||||
| 		 struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, | ||||
|  | @ -553,8 +558,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname) | |||
| 
 | ||||
| 	/* BB what if DFS and this volume is on different share? BB */ | ||||
| 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) | ||||
| 		rc = create_mf_symlink(xid, pTcon, full_path, symname, | ||||
| 					cifs_sb); | ||||
| 		rc = create_mf_symlink(xid, pTcon, cifs_sb, full_path, symname); | ||||
| 	else if (pTcon->unix_ext) | ||||
| 		rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname, | ||||
| 					   cifs_sb->local_nls); | ||||
|  |  | |||
|  | @ -1010,6 +1010,7 @@ struct smb_version_operations smb1_operations = { | |||
| 	.mand_unlock_range = cifs_unlock_range, | ||||
| 	.push_mand_locks = cifs_push_mandatory_locks, | ||||
| 	.query_mf_symlink = cifs_query_mf_symlink, | ||||
| 	.create_mf_symlink = cifs_create_mf_symlink, | ||||
| 	.is_read_op = cifs_is_read_op, | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Sachin Prabhu
				Sachin Prabhu