diff options
| -rw-r--r-- | fs/cifs/link.c | 61 |
1 files changed, 20 insertions, 41 deletions
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 500bc77a786e..77dbd55795d8 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
| @@ -237,55 +237,36 @@ create_mf_symlink(const unsigned int xid, struct cifs_tcon *tcon, | |||
| 237 | 237 | ||
| 238 | static int | 238 | static int |
| 239 | query_mf_symlink(const unsigned int xid, struct cifs_tcon *tcon, | 239 | query_mf_symlink(const unsigned int xid, struct cifs_tcon *tcon, |
| 240 | const unsigned char *searchName, char **symlinkinfo, | 240 | struct cifs_sb_info *cifs_sb, const unsigned char *path, |
| 241 | const struct nls_table *nls_codepage, int remap) | 241 | char **symlinkinfo) |
| 242 | { | 242 | { |
| 243 | int rc; | 243 | int rc; |
| 244 | int oplock = 0; | 244 | u8 *buf = NULL; |
| 245 | __u16 netfid = 0; | ||
| 246 | u8 *buf; | ||
| 247 | char *pbuf; | ||
| 248 | unsigned int bytes_read = 0; | ||
| 249 | int buf_type = CIFS_NO_BUFFER; | ||
| 250 | unsigned int link_len = 0; | 245 | unsigned int link_len = 0; |
| 251 | struct cifs_io_parms io_parms; | 246 | unsigned int bytes_read = 0; |
| 252 | FILE_ALL_INFO file_info; | ||
| 253 | |||
| 254 | rc = CIFSSMBOpen(xid, tcon, searchName, FILE_OPEN, GENERIC_READ, | ||
| 255 | CREATE_NOT_DIR, &netfid, &oplock, &file_info, | ||
| 256 | nls_codepage, remap); | ||
| 257 | if (rc != 0) | ||
| 258 | return rc; | ||
| 259 | |||
| 260 | if (file_info.EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) { | ||
| 261 | CIFSSMBClose(xid, tcon, netfid); | ||
| 262 | /* it's not a symlink */ | ||
| 263 | return -EINVAL; | ||
| 264 | } | ||
| 265 | 247 | ||
| 266 | buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL); | 248 | buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL); |
| 267 | if (!buf) | 249 | if (!buf) |
| 268 | return -ENOMEM; | 250 | return -ENOMEM; |
| 269 | pbuf = buf; | ||
| 270 | io_parms.netfid = netfid; | ||
| 271 | io_parms.pid = current->tgid; | ||
| 272 | io_parms.tcon = tcon; | ||
| 273 | io_parms.offset = 0; | ||
| 274 | io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE; | ||
| 275 | 251 | ||
| 276 | rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf, &buf_type); | 252 | if (tcon->ses->server->ops->query_mf_symlink) |
| 277 | CIFSSMBClose(xid, tcon, netfid); | 253 | rc = tcon->ses->server->ops->query_mf_symlink(xid, tcon, |
| 278 | if (rc != 0) { | 254 | cifs_sb, path, buf, &bytes_read); |
| 279 | kfree(buf); | 255 | else |
| 280 | return rc; | 256 | rc = -ENOSYS; |
| 257 | |||
| 258 | if (rc) | ||
| 259 | goto out; | ||
| 260 | |||
| 261 | if (bytes_read == 0) { /* not a symlink */ | ||
| 262 | rc = -EINVAL; | ||
| 263 | goto out; | ||
| 281 | } | 264 | } |
| 282 | 265 | ||
| 283 | rc = parse_mf_symlink(buf, bytes_read, &link_len, symlinkinfo); | 266 | rc = parse_mf_symlink(buf, bytes_read, &link_len, symlinkinfo); |
| 267 | out: | ||
| 284 | kfree(buf); | 268 | kfree(buf); |
| 285 | if (rc != 0) | 269 | return rc; |
| 286 | return rc; | ||
| 287 | |||
| 288 | return 0; | ||
| 289 | } | 270 | } |
| 290 | 271 | ||
| 291 | bool | 272 | bool |
| @@ -517,10 +498,8 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd) | |||
| 517 | * and fallback to UNIX Extensions Symlinks. | 498 | * and fallback to UNIX Extensions Symlinks. |
| 518 | */ | 499 | */ |
| 519 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) | 500 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) |
| 520 | rc = query_mf_symlink(xid, tcon, full_path, &target_path, | 501 | rc = query_mf_symlink(xid, tcon, cifs_sb, full_path, |
| 521 | cifs_sb->local_nls, | 502 | &target_path); |
| 522 | cifs_sb->mnt_cifs_flags & | ||
| 523 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
| 524 | 503 | ||
| 525 | if ((rc != 0) && cap_unix(tcon->ses)) | 504 | if ((rc != 0) && cap_unix(tcon->ses)) |
| 526 | rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path, | 505 | rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path, |
