aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/link.c63
-rw-r--r--fs/cifs/smb2ops.c2
-rw-r--r--fs/cifs/smb2proto.h4
3 files changed, 68 insertions, 1 deletions
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 5657416d3483..1216f4f1c6c9 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -28,6 +28,7 @@
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#include "smb2proto.h"
31 32
32/* 33/*
33 * M-F Symlink Functions - Begin 34 * M-F Symlink Functions - Begin
@@ -400,6 +401,68 @@ cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
400 return rc; 401 return rc;
401} 402}
402 403
404int
405smb3_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
406 struct cifs_sb_info *cifs_sb, const unsigned char *path,
407 char *pbuf, unsigned int *pbytes_written)
408{
409 int rc;
410 struct cifs_fid fid;
411 struct cifs_open_parms oparms;
412 struct cifs_io_parms io_parms;
413 int create_options = CREATE_NOT_DIR;
414 __le16 *utf16_path;
415 __u8 oplock = SMB2_OPLOCK_LEVEL_EXCLUSIVE;
416 struct kvec iov[2];
417
418 if (backup_cred(cifs_sb))
419 create_options |= CREATE_OPEN_BACKUP_INTENT;
420
421 cifs_dbg(FYI, "%s: path: %s\n", __func__, path);
422
423 utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
424 if (!utf16_path)
425 return -ENOMEM;
426
427 oparms.tcon = tcon;
428 oparms.cifs_sb = cifs_sb;
429 oparms.desired_access = GENERIC_WRITE;
430 oparms.create_options = create_options;
431 oparms.disposition = FILE_CREATE;
432 oparms.fid = &fid;
433 oparms.reconnect = false;
434
435 rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL);
436 if (rc) {
437 kfree(utf16_path);
438 return rc;
439 }
440
441 io_parms.netfid = fid.netfid;
442 io_parms.pid = current->tgid;
443 io_parms.tcon = tcon;
444 io_parms.offset = 0;
445 io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
446 io_parms.persistent_fid = fid.persistent_fid;
447 io_parms.volatile_fid = fid.volatile_fid;
448
449 /* iov[0] is reserved for smb header */
450 iov[1].iov_base = pbuf;
451 iov[1].iov_len = CIFS_MF_SYMLINK_FILE_SIZE;
452
453 rc = SMB2_write(xid, &io_parms, pbytes_written, iov, 1);
454
455 /* Make sure we wrote all of the symlink data */
456 if ((rc == 0) && (*pbytes_written != CIFS_MF_SYMLINK_FILE_SIZE))
457 rc = -EIO;
458
459 SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
460
461 kfree(utf16_path);
462 return rc;
463}
464
465
403/* 466/*
404 * M-F Symlink Functions - End 467 * M-F Symlink Functions - End
405 */ 468 */
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index ea158c9dea15..5e35d51504fd 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -1452,6 +1452,7 @@ struct smb_version_operations smb21_operations = {
1452 .rename = smb2_rename_path, 1452 .rename = smb2_rename_path,
1453 .create_hardlink = smb2_create_hardlink, 1453 .create_hardlink = smb2_create_hardlink,
1454 .query_symlink = smb2_query_symlink, 1454 .query_symlink = smb2_query_symlink,
1455 .create_mf_symlink = smb3_create_mf_symlink,
1455 .open = smb2_open_file, 1456 .open = smb2_open_file,
1456 .set_fid = smb2_set_fid, 1457 .set_fid = smb2_set_fid,
1457 .close = smb2_close_file, 1458 .close = smb2_close_file,
@@ -1531,6 +1532,7 @@ struct smb_version_operations smb30_operations = {
1531 .rename = smb2_rename_path, 1532 .rename = smb2_rename_path,
1532 .create_hardlink = smb2_create_hardlink, 1533 .create_hardlink = smb2_create_hardlink,
1533 .query_symlink = smb2_query_symlink, 1534 .query_symlink = smb2_query_symlink,
1535 .create_mf_symlink = smb3_create_mf_symlink,
1534 .open = smb2_open_file, 1536 .open = smb2_open_file,
1535 .set_fid = smb2_set_fid, 1537 .set_fid = smb2_set_fid,
1536 .close = smb2_close_file, 1538 .close = smb2_close_file,
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h
index 67e8ce8055de..e144ecfaa797 100644
--- a/fs/cifs/smb2proto.h
+++ b/fs/cifs/smb2proto.h
@@ -82,7 +82,9 @@ extern int smb2_rename_path(const unsigned int xid, struct cifs_tcon *tcon,
82extern int smb2_create_hardlink(const unsigned int xid, struct cifs_tcon *tcon, 82extern int smb2_create_hardlink(const unsigned int xid, struct cifs_tcon *tcon,
83 const char *from_name, const char *to_name, 83 const char *from_name, const char *to_name,
84 struct cifs_sb_info *cifs_sb); 84 struct cifs_sb_info *cifs_sb);
85 85extern int smb3_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
86 struct cifs_sb_info *cifs_sb, const unsigned char *path,
87 char *pbuf, unsigned int *pbytes_written);
86extern int smb2_open_file(const unsigned int xid, 88extern int smb2_open_file(const unsigned int xid,
87 struct cifs_open_parms *oparms, 89 struct cifs_open_parms *oparms,
88 __u32 *oplock, FILE_ALL_INFO *buf); 90 __u32 *oplock, FILE_ALL_INFO *buf);