Loading fs/cifs/smb2glob.h +1 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ #define SMB2_OP_MKDIR 5 #define SMB2_OP_RENAME 6 #define SMB2_OP_DELETE 7 #define SMB2_OP_HARDLINK 8 /* Used when constructing chained read requests. */ #define CHAINED_REQUEST 1 Loading fs/cifs/smb2inode.c +28 −6 Original line number Diff line number Diff line Loading @@ -78,6 +78,10 @@ smb2_open_op_close(const unsigned int xid, struct cifs_tcon *tcon, tmprc = SMB2_rename(xid, tcon, persistent_fid, volatile_fid, (__le16 *)data); break; case SMB2_OP_HARDLINK: tmprc = SMB2_set_hardlink(xid, tcon, persistent_fid, volatile_fid, (__le16 *)data); break; default: cERROR(1, "Invalid command"); break; Loading Loading @@ -175,10 +179,10 @@ smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon, const char *name, SMB2_OP_DELETE); } int smb2_rename_path(const unsigned int xid, struct cifs_tcon *tcon, static int smb2_set_path_attr(const unsigned int xid, struct cifs_tcon *tcon, const char *from_name, const char *to_name, struct cifs_sb_info *cifs_sb) struct cifs_sb_info *cifs_sb, __u32 access, int command) { __le16 *smb2_to_name = NULL; int rc; Loading @@ -189,9 +193,27 @@ smb2_rename_path(const unsigned int xid, struct cifs_tcon *tcon, goto smb2_rename_path; } rc = smb2_open_op_close(xid, tcon, cifs_sb, from_name, DELETE, FILE_OPEN, 0, 0, smb2_to_name, SMB2_OP_RENAME); rc = smb2_open_op_close(xid, tcon, cifs_sb, from_name, access, FILE_OPEN, 0, 0, smb2_to_name, command); smb2_rename_path: kfree(smb2_to_name); return rc; } int smb2_rename_path(const unsigned int xid, struct cifs_tcon *tcon, const char *from_name, const char *to_name, struct cifs_sb_info *cifs_sb) { return smb2_set_path_attr(xid, tcon, from_name, to_name, cifs_sb, DELETE, SMB2_OP_RENAME); } int smb2_create_hardlink(const unsigned int xid, struct cifs_tcon *tcon, const char *from_name, const char *to_name, struct cifs_sb_info *cifs_sb) { return smb2_set_path_attr(xid, tcon, from_name, to_name, cifs_sb, FILE_READ_ATTRIBUTES, SMB2_OP_HARDLINK); } fs/cifs/smb2ops.c +1 −0 Original line number Diff line number Diff line Loading @@ -452,6 +452,7 @@ struct smb_version_operations smb21_operations = { .rmdir = smb2_rmdir, .unlink = smb2_unlink, .rename = smb2_rename_path, .create_hardlink = smb2_create_hardlink, .open = smb2_open_file, .set_fid = smb2_set_fid, .close = smb2_close_file, Loading fs/cifs/smb2pdu.c +31 −0 Original line number Diff line number Diff line Loading @@ -1709,3 +1709,34 @@ SMB2_rename(const unsigned int xid, struct cifs_tcon *tcon, kfree(data); return rc; } int SMB2_set_hardlink(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, u64 volatile_fid, __le16 *target_file) { struct smb2_file_link_info info; void **data; unsigned int size[2]; int rc; int len = (2 * UniStrnlen((wchar_t *)target_file, PATH_MAX)); data = kmalloc(sizeof(void *) * 2, GFP_KERNEL); if (!data) return -ENOMEM; info.ReplaceIfExists = 0; /* 1 = replace existing link with new */ /* 0 = fail if link already exists */ info.RootDirectory = 0; /* MBZ for network ops (why does spec say?) */ info.FileNameLength = cpu_to_le32(len); data[0] = &info; size[0] = sizeof(struct smb2_file_link_info); data[1] = target_file; size[1] = len + 2 /* null */; rc = send_set_info(xid, tcon, persistent_fid, volatile_fid, FILE_LINK_INFORMATION, 2, data, size); kfree(data); return rc; } fs/cifs/smb2pdu.h +9 −0 Original line number Diff line number Diff line Loading @@ -653,6 +653,15 @@ struct smb2_file_rename_info { /* encoding of request for level 10 */ char FileName[0]; /* New name to be assigned */ } __packed; /* level 10 Set */ struct smb2_file_link_info { /* encoding of request for level 11 */ __u8 ReplaceIfExists; /* 1 = replace existing link with new */ /* 0 = fail if link already exists */ __u8 Reserved[7]; __u64 RootDirectory; /* MBZ for network operations (why says spec?) */ __le32 FileNameLength; char FileName[0]; /* Name to be assigned to new link */ } __packed; /* level 11 Set */ /* * This level 18, although with struct with same name is different from cifs * level 0x107. Level 0x107 has an extra u64 between AccessFlags and Loading Loading
fs/cifs/smb2glob.h +1 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ #define SMB2_OP_MKDIR 5 #define SMB2_OP_RENAME 6 #define SMB2_OP_DELETE 7 #define SMB2_OP_HARDLINK 8 /* Used when constructing chained read requests. */ #define CHAINED_REQUEST 1 Loading
fs/cifs/smb2inode.c +28 −6 Original line number Diff line number Diff line Loading @@ -78,6 +78,10 @@ smb2_open_op_close(const unsigned int xid, struct cifs_tcon *tcon, tmprc = SMB2_rename(xid, tcon, persistent_fid, volatile_fid, (__le16 *)data); break; case SMB2_OP_HARDLINK: tmprc = SMB2_set_hardlink(xid, tcon, persistent_fid, volatile_fid, (__le16 *)data); break; default: cERROR(1, "Invalid command"); break; Loading Loading @@ -175,10 +179,10 @@ smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon, const char *name, SMB2_OP_DELETE); } int smb2_rename_path(const unsigned int xid, struct cifs_tcon *tcon, static int smb2_set_path_attr(const unsigned int xid, struct cifs_tcon *tcon, const char *from_name, const char *to_name, struct cifs_sb_info *cifs_sb) struct cifs_sb_info *cifs_sb, __u32 access, int command) { __le16 *smb2_to_name = NULL; int rc; Loading @@ -189,9 +193,27 @@ smb2_rename_path(const unsigned int xid, struct cifs_tcon *tcon, goto smb2_rename_path; } rc = smb2_open_op_close(xid, tcon, cifs_sb, from_name, DELETE, FILE_OPEN, 0, 0, smb2_to_name, SMB2_OP_RENAME); rc = smb2_open_op_close(xid, tcon, cifs_sb, from_name, access, FILE_OPEN, 0, 0, smb2_to_name, command); smb2_rename_path: kfree(smb2_to_name); return rc; } int smb2_rename_path(const unsigned int xid, struct cifs_tcon *tcon, const char *from_name, const char *to_name, struct cifs_sb_info *cifs_sb) { return smb2_set_path_attr(xid, tcon, from_name, to_name, cifs_sb, DELETE, SMB2_OP_RENAME); } int smb2_create_hardlink(const unsigned int xid, struct cifs_tcon *tcon, const char *from_name, const char *to_name, struct cifs_sb_info *cifs_sb) { return smb2_set_path_attr(xid, tcon, from_name, to_name, cifs_sb, FILE_READ_ATTRIBUTES, SMB2_OP_HARDLINK); }
fs/cifs/smb2ops.c +1 −0 Original line number Diff line number Diff line Loading @@ -452,6 +452,7 @@ struct smb_version_operations smb21_operations = { .rmdir = smb2_rmdir, .unlink = smb2_unlink, .rename = smb2_rename_path, .create_hardlink = smb2_create_hardlink, .open = smb2_open_file, .set_fid = smb2_set_fid, .close = smb2_close_file, Loading
fs/cifs/smb2pdu.c +31 −0 Original line number Diff line number Diff line Loading @@ -1709,3 +1709,34 @@ SMB2_rename(const unsigned int xid, struct cifs_tcon *tcon, kfree(data); return rc; } int SMB2_set_hardlink(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, u64 volatile_fid, __le16 *target_file) { struct smb2_file_link_info info; void **data; unsigned int size[2]; int rc; int len = (2 * UniStrnlen((wchar_t *)target_file, PATH_MAX)); data = kmalloc(sizeof(void *) * 2, GFP_KERNEL); if (!data) return -ENOMEM; info.ReplaceIfExists = 0; /* 1 = replace existing link with new */ /* 0 = fail if link already exists */ info.RootDirectory = 0; /* MBZ for network ops (why does spec say?) */ info.FileNameLength = cpu_to_le32(len); data[0] = &info; size[0] = sizeof(struct smb2_file_link_info); data[1] = target_file; size[1] = len + 2 /* null */; rc = send_set_info(xid, tcon, persistent_fid, volatile_fid, FILE_LINK_INFORMATION, 2, data, size); kfree(data); return rc; }
fs/cifs/smb2pdu.h +9 −0 Original line number Diff line number Diff line Loading @@ -653,6 +653,15 @@ struct smb2_file_rename_info { /* encoding of request for level 10 */ char FileName[0]; /* New name to be assigned */ } __packed; /* level 10 Set */ struct smb2_file_link_info { /* encoding of request for level 11 */ __u8 ReplaceIfExists; /* 1 = replace existing link with new */ /* 0 = fail if link already exists */ __u8 Reserved[7]; __u64 RootDirectory; /* MBZ for network operations (why says spec?) */ __le32 FileNameLength; char FileName[0]; /* Name to be assigned to new link */ } __packed; /* level 11 Set */ /* * This level 18, although with struct with same name is different from cifs * level 0x107. Level 0x107 has an extra u64 between AccessFlags and Loading