diff options
author | Pavel Shilovsky <pshilovsky@samba.org> | 2012-09-18 19:20:32 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2012-09-24 22:46:29 -0400 |
commit | c839ff244ba2d54d0933596e29a4b03e3c846a9a (patch) | |
tree | 91c58400bd08c1e5a18ed33cca16f7b890be5dde | |
parent | d143341815bdc7c45d5289a3ab5743c838332518 (diff) |
CIFS: Add SMB2 support for set_file_size
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org>
Signed-off-by: Steve French <smfrench@gmail.com>
-rw-r--r-- | fs/cifs/smb2glob.h | 1 | ||||
-rw-r--r-- | fs/cifs/smb2inode.c | 15 | ||||
-rw-r--r-- | fs/cifs/smb2ops.c | 11 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.c | 26 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.h | 4 | ||||
-rw-r--r-- | fs/cifs/smb2proto.h | 6 |
6 files changed, 60 insertions, 3 deletions
diff --git a/fs/cifs/smb2glob.h b/fs/cifs/smb2glob.h index 21555d8744fd..05d429b1c37e 100644 --- a/fs/cifs/smb2glob.h +++ b/fs/cifs/smb2glob.h | |||
@@ -41,6 +41,7 @@ | |||
41 | #define SMB2_OP_RENAME 6 | 41 | #define SMB2_OP_RENAME 6 |
42 | #define SMB2_OP_DELETE 7 | 42 | #define SMB2_OP_DELETE 7 |
43 | #define SMB2_OP_HARDLINK 8 | 43 | #define SMB2_OP_HARDLINK 8 |
44 | #define SMB2_OP_SET_EOF 9 | ||
44 | 45 | ||
45 | /* Used when constructing chained read requests. */ | 46 | /* Used when constructing chained read requests. */ |
46 | #define CHAINED_REQUEST 1 | 47 | #define CHAINED_REQUEST 1 |
diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c index 1921c9c87ccd..290583092293 100644 --- a/fs/cifs/smb2inode.c +++ b/fs/cifs/smb2inode.c | |||
@@ -82,6 +82,10 @@ smb2_open_op_close(const unsigned int xid, struct cifs_tcon *tcon, | |||
82 | tmprc = SMB2_set_hardlink(xid, tcon, persistent_fid, | 82 | tmprc = SMB2_set_hardlink(xid, tcon, persistent_fid, |
83 | volatile_fid, (__le16 *)data); | 83 | volatile_fid, (__le16 *)data); |
84 | break; | 84 | break; |
85 | case SMB2_OP_SET_EOF: | ||
86 | tmprc = SMB2_set_eof(xid, tcon, persistent_fid, volatile_fid, | ||
87 | current->tgid, (__le64 *)data); | ||
88 | break; | ||
85 | default: | 89 | default: |
86 | cERROR(1, "Invalid command"); | 90 | cERROR(1, "Invalid command"); |
87 | break; | 91 | break; |
@@ -217,3 +221,14 @@ smb2_create_hardlink(const unsigned int xid, struct cifs_tcon *tcon, | |||
217 | return smb2_set_path_attr(xid, tcon, from_name, to_name, cifs_sb, | 221 | return smb2_set_path_attr(xid, tcon, from_name, to_name, cifs_sb, |
218 | FILE_READ_ATTRIBUTES, SMB2_OP_HARDLINK); | 222 | FILE_READ_ATTRIBUTES, SMB2_OP_HARDLINK); |
219 | } | 223 | } |
224 | |||
225 | int | ||
226 | smb2_set_path_size(const unsigned int xid, struct cifs_tcon *tcon, | ||
227 | const char *full_path, __u64 size, | ||
228 | struct cifs_sb_info *cifs_sb, bool set_alloc) | ||
229 | { | ||
230 | __le64 eof = cpu_to_le64(size); | ||
231 | return smb2_open_op_close(xid, tcon, cifs_sb, full_path, | ||
232 | FILE_WRITE_DATA, FILE_OPEN, 0, 0, &eof, | ||
233 | SMB2_OP_SET_EOF); | ||
234 | } | ||
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 75693e983e76..e0daf3a4dcc2 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
@@ -415,6 +415,15 @@ smb2_sync_write(const unsigned int xid, struct cifsFileInfo *cfile, | |||
415 | return SMB2_write(xid, parms, written, iov, nr_segs); | 415 | return SMB2_write(xid, parms, written, iov, nr_segs); |
416 | } | 416 | } |
417 | 417 | ||
418 | static int | ||
419 | smb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon, | ||
420 | struct cifsFileInfo *cfile, __u64 size, bool set_alloc) | ||
421 | { | ||
422 | __le64 eof = cpu_to_le64(size); | ||
423 | return SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid, | ||
424 | cfile->fid.volatile_fid, cfile->pid, &eof); | ||
425 | } | ||
426 | |||
418 | struct smb_version_operations smb21_operations = { | 427 | struct smb_version_operations smb21_operations = { |
419 | .setup_request = smb2_setup_request, | 428 | .setup_request = smb2_setup_request, |
420 | .setup_async_request = smb2_setup_async_request, | 429 | .setup_async_request = smb2_setup_async_request, |
@@ -446,6 +455,8 @@ struct smb_version_operations smb21_operations = { | |||
446 | .query_path_info = smb2_query_path_info, | 455 | .query_path_info = smb2_query_path_info, |
447 | .get_srv_inum = smb2_get_srv_inum, | 456 | .get_srv_inum = smb2_get_srv_inum, |
448 | .query_file_info = smb2_query_file_info, | 457 | .query_file_info = smb2_query_file_info, |
458 | .set_path_size = smb2_set_path_size, | ||
459 | .set_file_size = smb2_set_file_size, | ||
449 | .build_path_to_root = smb2_build_path_to_root, | 460 | .build_path_to_root = smb2_build_path_to_root, |
450 | .mkdir = smb2_mkdir, | 461 | .mkdir = smb2_mkdir, |
451 | .mkdir_setinfo = smb2_mkdir_setinfo, | 462 | .mkdir_setinfo = smb2_mkdir_setinfo, |
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index a684c4ab42d6..74a8381400b1 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
@@ -1605,7 +1605,7 @@ SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms, | |||
1605 | 1605 | ||
1606 | static int | 1606 | static int |
1607 | send_set_info(const unsigned int xid, struct cifs_tcon *tcon, | 1607 | send_set_info(const unsigned int xid, struct cifs_tcon *tcon, |
1608 | u64 persistent_fid, u64 volatile_fid, int info_class, | 1608 | u64 persistent_fid, u64 volatile_fid, u32 pid, int info_class, |
1609 | unsigned int num, void **data, unsigned int *size) | 1609 | unsigned int num, void **data, unsigned int *size) |
1610 | { | 1610 | { |
1611 | struct smb2_set_info_req *req; | 1611 | struct smb2_set_info_req *req; |
@@ -1635,6 +1635,8 @@ send_set_info(const unsigned int xid, struct cifs_tcon *tcon, | |||
1635 | return rc; | 1635 | return rc; |
1636 | } | 1636 | } |
1637 | 1637 | ||
1638 | req->hdr.ProcessId = cpu_to_le32(pid); | ||
1639 | |||
1638 | req->InfoType = SMB2_O_INFO_FILE; | 1640 | req->InfoType = SMB2_O_INFO_FILE; |
1639 | req->FileInfoClass = info_class; | 1641 | req->FileInfoClass = info_class; |
1640 | req->PersistentFileId = persistent_fid; | 1642 | req->PersistentFileId = persistent_fid; |
@@ -1705,7 +1707,8 @@ SMB2_rename(const unsigned int xid, struct cifs_tcon *tcon, | |||
1705 | size[1] = len + 2 /* null */; | 1707 | size[1] = len + 2 /* null */; |
1706 | 1708 | ||
1707 | rc = send_set_info(xid, tcon, persistent_fid, volatile_fid, | 1709 | rc = send_set_info(xid, tcon, persistent_fid, volatile_fid, |
1708 | FILE_RENAME_INFORMATION, 2, data, size); | 1710 | current->tgid, FILE_RENAME_INFORMATION, 2, data, |
1711 | size); | ||
1709 | kfree(data); | 1712 | kfree(data); |
1710 | return rc; | 1713 | return rc; |
1711 | } | 1714 | } |
@@ -1736,7 +1739,24 @@ SMB2_set_hardlink(const unsigned int xid, struct cifs_tcon *tcon, | |||
1736 | size[1] = len + 2 /* null */; | 1739 | size[1] = len + 2 /* null */; |
1737 | 1740 | ||
1738 | rc = send_set_info(xid, tcon, persistent_fid, volatile_fid, | 1741 | rc = send_set_info(xid, tcon, persistent_fid, volatile_fid, |
1739 | FILE_LINK_INFORMATION, 2, data, size); | 1742 | current->tgid, FILE_LINK_INFORMATION, 2, data, size); |
1740 | kfree(data); | 1743 | kfree(data); |
1741 | return rc; | 1744 | return rc; |
1742 | } | 1745 | } |
1746 | |||
1747 | int | ||
1748 | SMB2_set_eof(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, | ||
1749 | u64 volatile_fid, u32 pid, __le64 *eof) | ||
1750 | { | ||
1751 | struct smb2_file_eof_info info; | ||
1752 | void *data; | ||
1753 | unsigned int size; | ||
1754 | |||
1755 | info.EndOfFile = *eof; | ||
1756 | |||
1757 | data = &info; | ||
1758 | size = sizeof(struct smb2_file_eof_info); | ||
1759 | |||
1760 | return send_set_info(xid, tcon, persistent_fid, volatile_fid, pid, | ||
1761 | FILE_END_OF_FILE_INFORMATION, 1, &data, &size); | ||
1762 | } | ||
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index 0f3c4828cd00..d775941f552a 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h | |||
@@ -690,4 +690,8 @@ struct smb2_file_all_info { /* data block encoding of response to level 18 */ | |||
690 | char FileName[1]; | 690 | char FileName[1]; |
691 | } __packed; /* level 18 Query */ | 691 | } __packed; /* level 18 Query */ |
692 | 692 | ||
693 | struct smb2_file_eof_info { /* encoding of request for level 10 */ | ||
694 | __le64 EndOfFile; /* new end of file value */ | ||
695 | } __packed; /* level 20 Set */ | ||
696 | |||
693 | #endif /* _SMB2PDU_H */ | 697 | #endif /* _SMB2PDU_H */ |
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h index 99f6945c8643..3d4866279530 100644 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h | |||
@@ -56,6 +56,9 @@ extern int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, | |||
56 | struct cifs_sb_info *cifs_sb, | 56 | struct cifs_sb_info *cifs_sb, |
57 | const char *full_path, FILE_ALL_INFO *data, | 57 | const char *full_path, FILE_ALL_INFO *data, |
58 | bool *adjust_tz); | 58 | bool *adjust_tz); |
59 | extern int smb2_set_path_size(const unsigned int xid, struct cifs_tcon *tcon, | ||
60 | const char *full_path, __u64 size, | ||
61 | struct cifs_sb_info *cifs_sb, bool set_alloc); | ||
59 | extern int smb2_mkdir(const unsigned int xid, struct cifs_tcon *tcon, | 62 | extern int smb2_mkdir(const unsigned int xid, struct cifs_tcon *tcon, |
60 | const char *name, struct cifs_sb_info *cifs_sb); | 63 | const char *name, struct cifs_sb_info *cifs_sb); |
61 | extern void smb2_mkdir_setinfo(struct inode *inode, const char *full_path, | 64 | extern void smb2_mkdir_setinfo(struct inode *inode, const char *full_path, |
@@ -118,5 +121,8 @@ extern int SMB2_rename(const unsigned int xid, struct cifs_tcon *tcon, | |||
118 | extern int SMB2_set_hardlink(const unsigned int xid, struct cifs_tcon *tcon, | 121 | extern int SMB2_set_hardlink(const unsigned int xid, struct cifs_tcon *tcon, |
119 | u64 persistent_fid, u64 volatile_fid, | 122 | u64 persistent_fid, u64 volatile_fid, |
120 | __le16 *target_file); | 123 | __le16 *target_file); |
124 | extern int SMB2_set_eof(const unsigned int xid, struct cifs_tcon *tcon, | ||
125 | u64 persistent_fid, u64 volatile_fid, u32 pid, | ||
126 | __le64 *eof); | ||
121 | 127 | ||
122 | #endif /* _SMB2PROTO_H */ | 128 | #endif /* _SMB2PROTO_H */ |