aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/link.c
diff options
context:
space:
mode:
authorSteve French <smfrench@gmail.com>2014-09-16 08:18:19 -0400
committerSteve French <smfrench@gmail.com>2014-10-16 16:20:20 -0400
commitc22870ea2deb2841402133909cfa707a2c0b12ed (patch)
tree99a15884a9be669408c166a997b55944b5504388 /fs/cifs/link.c
parent5ab97578cbb3bf9a28dec4534cb86fbc35e600bb (diff)
mfsymlinks support for SMB2.1/SMB3. Part 2 query symlink
Adds support on SMB2.1 and SMB3 mounts for emulation of symlinks via the "Minshall/French" symlink format already used for cifs mounts when mfsymlinks mount option is used (and also used by Apple). http://wiki.samba.org/index.php/UNIX_Extensions#Minshall.2BFrench_symlinks This second patch adds support to query them (recognize them as symlinks and read them). Third version of patch makes minor corrections to error handling. Signed-off-by: Steve French <smfrench@gmail.com> Reviewed-by: Stefan Metzmacher <metze@samba.org>
Diffstat (limited to 'fs/cifs/link.c')
-rw-r--r--fs/cifs/link.c70
1 files changed, 69 insertions, 1 deletions
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 1216f4f1c6c9..ce7d4bbf3120 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -28,7 +28,9 @@
28#include "cifsproto.h" 28#include "cifsproto.h"
29#include "cifs_debug.h" 29#include "cifs_debug.h"
30#include "cifs_fs_sb.h" 30#include "cifs_fs_sb.h"
31#ifdef CONFIG_CIFS_SMB2
31#include "smb2proto.h" 32#include "smb2proto.h"
33#endif
32 34
33/* 35/*
34 * M-F Symlink Functions - Begin 36 * M-F Symlink Functions - Begin
@@ -401,6 +403,72 @@ cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
401 return rc; 403 return rc;
402} 404}
403 405
406/*
407 * SMB 2.1/SMB3 Protocol specific functions
408 */
409#ifdef CONFIG_CIFS_SMB2
410int
411smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
412 struct cifs_sb_info *cifs_sb, const unsigned char *path,
413 char *pbuf, unsigned int *pbytes_read)
414{
415 int rc;
416 struct cifs_fid fid;
417 struct cifs_open_parms oparms;
418 struct cifs_io_parms io_parms;
419 int buf_type = CIFS_NO_BUFFER;
420 __le16 *utf16_path;
421 __u8 oplock = SMB2_OPLOCK_LEVEL_II;
422 struct smb2_file_all_info *pfile_info = NULL;
423
424 oparms.tcon = tcon;
425 oparms.cifs_sb = cifs_sb;
426 oparms.desired_access = GENERIC_READ;
427 oparms.create_options = CREATE_NOT_DIR;
428 if (backup_cred(cifs_sb))
429 oparms.create_options |= CREATE_OPEN_BACKUP_INTENT;
430 oparms.disposition = FILE_OPEN;
431 oparms.fid = &fid;
432 oparms.reconnect = false;
433
434 utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
435 if (utf16_path == NULL)
436 return -ENOMEM;
437
438 pfile_info = kzalloc(sizeof(struct smb2_file_all_info) + PATH_MAX * 2,
439 GFP_KERNEL);
440
441 if (pfile_info == NULL) {
442 kfree(utf16_path);
443 return -ENOMEM;
444 }
445
446 rc = SMB2_open(xid, &oparms, utf16_path, &oplock, pfile_info, NULL);
447 if (rc)
448 goto qmf_out_open_fail;
449
450 if (pfile_info->EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) {
451 /* it's not a symlink */
452 rc = -ENOENT; /* Is there a better rc to return? */
453 goto qmf_out;
454 }
455
456 io_parms.netfid = fid.netfid;
457 io_parms.pid = current->tgid;
458 io_parms.tcon = tcon;
459 io_parms.offset = 0;
460 io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
461 io_parms.persistent_fid = fid.persistent_fid;
462 io_parms.volatile_fid = fid.volatile_fid;
463 rc = SMB2_read(xid, &io_parms, pbytes_read, &pbuf, &buf_type);
464qmf_out:
465 SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
466qmf_out_open_fail:
467 kfree(utf16_path);
468 kfree(pfile_info);
469 return rc;
470}
471
404int 472int
405smb3_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, 473smb3_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
406 struct cifs_sb_info *cifs_sb, const unsigned char *path, 474 struct cifs_sb_info *cifs_sb, const unsigned char *path,
@@ -461,7 +529,7 @@ smb3_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
461 kfree(utf16_path); 529 kfree(utf16_path);
462 return rc; 530 return rc;
463} 531}
464 532#endif /* CONFIG_CIFS_SMB2 */
465 533
466/* 534/*
467 * M-F Symlink Functions - End 535 * M-F Symlink Functions - End