aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorPavel Shilovsky <pshilovsky@samba.org>2012-09-18 19:20:31 -0400
committerSteve French <smfrench@gmail.com>2012-09-24 22:46:29 -0400
commitd143341815bdc7c45d5289a3ab5743c838332518 (patch)
tree2e94221eb03a569e07fa4118b7d68c507f66efb4 /fs/cifs
parent568798cc6211553e2494a6876fa19d064c822e79 (diff)
CIFS: Move set_file_size to ops struct
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org> Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cifsglob.h6
-rw-r--r--fs/cifs/cifsproto.h10
-rw-r--r--fs/cifs/cifssmb.c40
-rw-r--r--fs/cifs/inode.c106
-rw-r--r--fs/cifs/smb1ops.c2
5 files changed, 89 insertions, 75 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 8595d498ad80..803c21218633 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -252,6 +252,12 @@ struct smb_version_operations {
252 int (*get_srv_inum)(const unsigned int, struct cifs_tcon *, 252 int (*get_srv_inum)(const unsigned int, struct cifs_tcon *,
253 struct cifs_sb_info *, const char *, 253 struct cifs_sb_info *, const char *,
254 u64 *uniqueid, FILE_ALL_INFO *); 254 u64 *uniqueid, FILE_ALL_INFO *);
255 /* set size by path */
256 int (*set_path_size)(const unsigned int, struct cifs_tcon *,
257 const char *, __u64, struct cifs_sb_info *, bool);
258 /* set size by file handle */
259 int (*set_file_size)(const unsigned int, struct cifs_tcon *,
260 struct cifsFileInfo *, __u64, bool);
255 /* build a full path to the root of the mount */ 261 /* build a full path to the root of the mount */
256 char * (*build_path_to_root)(struct smb_vol *, struct cifs_sb_info *, 262 char * (*build_path_to_root)(struct smb_vol *, struct cifs_sb_info *,
257 struct cifs_tcon *); 263 struct cifs_tcon *);
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 3c50555c7735..3d99fe9afccc 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -270,13 +270,11 @@ extern int CIFSSMBSetAttrLegacy(unsigned int xid, struct cifs_tcon *tcon,
270 const struct nls_table *nls_codepage); 270 const struct nls_table *nls_codepage);
271#endif /* possibly unneeded function */ 271#endif /* possibly unneeded function */
272extern int CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon, 272extern int CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
273 const char *fileName, __u64 size, 273 const char *file_name, __u64 size,
274 bool setAllocationSizeFlag, 274 struct cifs_sb_info *cifs_sb, bool set_allocation);
275 const struct nls_table *nls_codepage,
276 int remap_special_chars);
277extern int CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon, 275extern int CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
278 __u64 size, __u16 fileHandle, __u32 opener_pid, 276 struct cifsFileInfo *cfile, __u64 size,
279 bool AllocSizeFlag); 277 bool set_allocation);
280 278
281struct cifs_unix_set_info_args { 279struct cifs_unix_set_info_args {
282 __u64 ctime; 280 __u64 ctime;
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index eb3d2cf76e6e..c4f43cf671dc 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -5395,16 +5395,16 @@ QFSPosixRetry:
5395} 5395}
5396 5396
5397 5397
5398/* We can not use write of zero bytes trick to 5398/*
5399 set file size due to need for large file support. Also note that 5399 * We can not use write of zero bytes trick to set file size due to need for
5400 this SetPathInfo is preferred to SetFileInfo based method in next 5400 * large file support. Also note that this SetPathInfo is preferred to
5401 routine which is only needed to work around a sharing violation bug 5401 * SetFileInfo based method in next routine which is only needed to work around
5402 in Samba which this routine can run into */ 5402 * a sharing violation bugin Samba which this routine can run into.
5403 5403 */
5404int 5404int
5405CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon, 5405CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5406 const char *fileName, __u64 size, bool SetAllocation, 5406 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
5407 const struct nls_table *nls_codepage, int remap) 5407 bool set_allocation)
5408{ 5408{
5409 struct smb_com_transaction2_spi_req *pSMB = NULL; 5409 struct smb_com_transaction2_spi_req *pSMB = NULL;
5410 struct smb_com_transaction2_spi_rsp *pSMBr = NULL; 5410 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
@@ -5412,6 +5412,8 @@ CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5412 int name_len; 5412 int name_len;
5413 int rc = 0; 5413 int rc = 0;
5414 int bytes_returned = 0; 5414 int bytes_returned = 0;
5415 int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
5416
5415 __u16 params, byte_count, data_count, param_offset, offset; 5417 __u16 params, byte_count, data_count, param_offset, offset;
5416 5418
5417 cFYI(1, "In SetEOF"); 5419 cFYI(1, "In SetEOF");
@@ -5423,14 +5425,14 @@ SetEOFRetry:
5423 5425
5424 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5426 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5425 name_len = 5427 name_len =
5426 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName, 5428 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5427 PATH_MAX, nls_codepage, remap); 5429 PATH_MAX, cifs_sb->local_nls, remap);
5428 name_len++; /* trailing null */ 5430 name_len++; /* trailing null */
5429 name_len *= 2; 5431 name_len *= 2;
5430 } else { /* BB improve the check for buffer overruns BB */ 5432 } else { /* BB improve the check for buffer overruns BB */
5431 name_len = strnlen(fileName, PATH_MAX); 5433 name_len = strnlen(file_name, PATH_MAX);
5432 name_len++; /* trailing null */ 5434 name_len++; /* trailing null */
5433 strncpy(pSMB->FileName, fileName, name_len); 5435 strncpy(pSMB->FileName, file_name, name_len);
5434 } 5436 }
5435 params = 6 + name_len; 5437 params = 6 + name_len;
5436 data_count = sizeof(struct file_end_of_file_info); 5438 data_count = sizeof(struct file_end_of_file_info);
@@ -5444,7 +5446,7 @@ SetEOFRetry:
5444 param_offset = offsetof(struct smb_com_transaction2_spi_req, 5446 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5445 InformationLevel) - 4; 5447 InformationLevel) - 4;
5446 offset = param_offset + params; 5448 offset = param_offset + params;
5447 if (SetAllocation) { 5449 if (set_allocation) {
5448 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5450 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5449 pSMB->InformationLevel = 5451 pSMB->InformationLevel =
5450 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2); 5452 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
@@ -5491,8 +5493,8 @@ SetEOFRetry:
5491} 5493}
5492 5494
5493int 5495int
5494CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon, __u64 size, 5496CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5495 __u16 fid, __u32 pid_of_opener, bool SetAllocation) 5497 struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5496{ 5498{
5497 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5499 struct smb_com_transaction2_sfi_req *pSMB = NULL;
5498 struct file_end_of_file_info *parm_data; 5500 struct file_end_of_file_info *parm_data;
@@ -5506,8 +5508,8 @@ CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon, __u64 size,
5506 if (rc) 5508 if (rc)
5507 return rc; 5509 return rc;
5508 5510
5509 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); 5511 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5510 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); 5512 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5511 5513
5512 params = 6; 5514 params = 6;
5513 pSMB->MaxSetupCount = 0; 5515 pSMB->MaxSetupCount = 0;
@@ -5536,8 +5538,8 @@ CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon, __u64 size,
5536 + offset); 5538 + offset);
5537 pSMB->DataOffset = cpu_to_le16(offset); 5539 pSMB->DataOffset = cpu_to_le16(offset);
5538 parm_data->FileSize = cpu_to_le64(size); 5540 parm_data->FileSize = cpu_to_le64(size);
5539 pSMB->Fid = fid; 5541 pSMB->Fid = cfile->fid.netfid;
5540 if (SetAllocation) { 5542 if (set_allocation) {
5541 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5543 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5542 pSMB->InformationLevel = 5544 pSMB->InformationLevel =
5543 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2); 5545 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 2f3235f08c3f..85e1b0a405a8 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1883,7 +1883,8 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1883 struct cifsInodeInfo *cifsInode = CIFS_I(inode); 1883 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1884 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 1884 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1885 struct tcon_link *tlink = NULL; 1885 struct tcon_link *tlink = NULL;
1886 struct cifs_tcon *pTcon = NULL; 1886 struct cifs_tcon *tcon = NULL;
1887 struct TCP_Server_Info *server;
1887 struct cifs_io_parms io_parms; 1888 struct cifs_io_parms io_parms;
1888 1889
1889 /* 1890 /*
@@ -1897,19 +1898,21 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1897 */ 1898 */
1898 open_file = find_writable_file(cifsInode, true); 1899 open_file = find_writable_file(cifsInode, true);
1899 if (open_file) { 1900 if (open_file) {
1900 __u16 nfid = open_file->fid.netfid; 1901 tcon = tlink_tcon(open_file->tlink);
1901 __u32 npid = open_file->pid; 1902 server = tcon->ses->server;
1902 pTcon = tlink_tcon(open_file->tlink); 1903 if (server->ops->set_file_size)
1903 rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid, 1904 rc = server->ops->set_file_size(xid, tcon, open_file,
1904 npid, false); 1905 attrs->ia_size, false);
1906 else
1907 rc = -ENOSYS;
1905 cifsFileInfo_put(open_file); 1908 cifsFileInfo_put(open_file);
1906 cFYI(1, "SetFSize for attrs rc = %d", rc); 1909 cFYI(1, "SetFSize for attrs rc = %d", rc);
1907 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { 1910 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1908 unsigned int bytes_written; 1911 unsigned int bytes_written;
1909 1912
1910 io_parms.netfid = nfid; 1913 io_parms.netfid = open_file->fid.netfid;
1911 io_parms.pid = npid; 1914 io_parms.pid = open_file->pid;
1912 io_parms.tcon = pTcon; 1915 io_parms.tcon = tcon;
1913 io_parms.offset = 0; 1916 io_parms.offset = 0;
1914 io_parms.length = attrs->ia_size; 1917 io_parms.length = attrs->ia_size;
1915 rc = CIFSSMBWrite(xid, &io_parms, &bytes_written, 1918 rc = CIFSSMBWrite(xid, &io_parms, &bytes_written,
@@ -1919,52 +1922,55 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1919 } else 1922 } else
1920 rc = -EINVAL; 1923 rc = -EINVAL;
1921 1924
1922 if (rc != 0) { 1925 if (!rc)
1923 if (pTcon == NULL) { 1926 goto set_size_out;
1924 tlink = cifs_sb_tlink(cifs_sb);
1925 if (IS_ERR(tlink))
1926 return PTR_ERR(tlink);
1927 pTcon = tlink_tcon(tlink);
1928 }
1929 1927
1930 /* Set file size by pathname rather than by handle 1928 if (tcon == NULL) {
1931 either because no valid, writeable file handle for 1929 tlink = cifs_sb_tlink(cifs_sb);
1932 it was found or because there was an error setting 1930 if (IS_ERR(tlink))
1933 it by handle */ 1931 return PTR_ERR(tlink);
1934 rc = CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size, 1932 tcon = tlink_tcon(tlink);
1935 false, cifs_sb->local_nls, 1933 server = tcon->ses->server;
1934 }
1935
1936 /*
1937 * Set file size by pathname rather than by handle either because no
1938 * valid, writeable file handle for it was found or because there was
1939 * an error setting it by handle.
1940 */
1941 if (server->ops->set_path_size)
1942 rc = server->ops->set_path_size(xid, tcon, full_path,
1943 attrs->ia_size, cifs_sb, false);
1944 else
1945 rc = -ENOSYS;
1946 cFYI(1, "SetEOF by path (setattrs) rc = %d", rc);
1947 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1948 __u16 netfid;
1949 int oplock = 0;
1950
1951 rc = SMBLegacyOpen(xid, tcon, full_path, FILE_OPEN,
1952 GENERIC_WRITE, CREATE_NOT_DIR, &netfid,
1953 &oplock, NULL, cifs_sb->local_nls,
1936 cifs_sb->mnt_cifs_flags & 1954 cifs_sb->mnt_cifs_flags &
1937 CIFS_MOUNT_MAP_SPECIAL_CHR); 1955 CIFS_MOUNT_MAP_SPECIAL_CHR);
1938 cFYI(1, "SetEOF by path (setattrs) rc = %d", rc); 1956 if (rc == 0) {
1939 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { 1957 unsigned int bytes_written;
1940 __u16 netfid; 1958
1941 int oplock = 0; 1959 io_parms.netfid = netfid;
1942 1960 io_parms.pid = current->tgid;
1943 rc = SMBLegacyOpen(xid, pTcon, full_path, 1961 io_parms.tcon = tcon;
1944 FILE_OPEN, GENERIC_WRITE, 1962 io_parms.offset = 0;
1945 CREATE_NOT_DIR, &netfid, &oplock, NULL, 1963 io_parms.length = attrs->ia_size;
1946 cifs_sb->local_nls, 1964 rc = CIFSSMBWrite(xid, &io_parms, &bytes_written, NULL,
1947 cifs_sb->mnt_cifs_flags & 1965 NULL, 1);
1948 CIFS_MOUNT_MAP_SPECIAL_CHR); 1966 cFYI(1, "wrt seteof rc %d", rc);
1949 if (rc == 0) { 1967 CIFSSMBClose(xid, tcon, netfid);
1950 unsigned int bytes_written;
1951
1952 io_parms.netfid = netfid;
1953 io_parms.pid = current->tgid;
1954 io_parms.tcon = pTcon;
1955 io_parms.offset = 0;
1956 io_parms.length = attrs->ia_size;
1957 rc = CIFSSMBWrite(xid, &io_parms,
1958 &bytes_written,
1959 NULL, NULL, 1);
1960 cFYI(1, "wrt seteof rc %d", rc);
1961 CIFSSMBClose(xid, pTcon, netfid);
1962 }
1963 } 1968 }
1964 if (tlink)
1965 cifs_put_tlink(tlink);
1966 } 1969 }
1970 if (tlink)
1971 cifs_put_tlink(tlink);
1967 1972
1973set_size_out:
1968 if (rc == 0) { 1974 if (rc == 0) {
1969 cifsInode->server_eof = attrs->ia_size; 1975 cifsInode->server_eof = attrs->ia_size;
1970 cifs_setsize(inode, attrs->ia_size); 1976 cifs_setsize(inode, attrs->ia_size);
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
index e5d63444f0ff..b73d2750296d 100644
--- a/fs/cifs/smb1ops.c
+++ b/fs/cifs/smb1ops.c
@@ -793,6 +793,8 @@ struct smb_version_operations smb1_operations = {
793 .query_path_info = cifs_query_path_info, 793 .query_path_info = cifs_query_path_info,
794 .query_file_info = cifs_query_file_info, 794 .query_file_info = cifs_query_file_info,
795 .get_srv_inum = cifs_get_srv_inum, 795 .get_srv_inum = cifs_get_srv_inum,
796 .set_path_size = CIFSSMBSetEOF,
797 .set_file_size = CIFSSMBSetFileSize,
796 .build_path_to_root = cifs_build_path_to_root, 798 .build_path_to_root = cifs_build_path_to_root,
797 .echo = CIFSSMBEcho, 799 .echo = CIFSSMBEcho,
798 .mkdir = CIFSSMBMkDir, 800 .mkdir = CIFSSMBMkDir,