CIFS: Move set_file_size to ops struct

Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org>
Signed-off-by: Steve French <smfrench@gmail.com>
This commit is contained in:
Pavel Shilovsky 2012-09-18 16:20:31 -07:00 committed by Steve French
parent 568798cc62
commit d143341815
5 changed files with 91 additions and 77 deletions

View File

@ -252,6 +252,12 @@ struct smb_version_operations {
int (*get_srv_inum)(const unsigned int, struct cifs_tcon *, int (*get_srv_inum)(const unsigned int, struct cifs_tcon *,
struct cifs_sb_info *, const char *, struct cifs_sb_info *, const char *,
u64 *uniqueid, FILE_ALL_INFO *); u64 *uniqueid, FILE_ALL_INFO *);
/* set size by path */
int (*set_path_size)(const unsigned int, struct cifs_tcon *,
const char *, __u64, struct cifs_sb_info *, bool);
/* set size by file handle */
int (*set_file_size)(const unsigned int, struct cifs_tcon *,
struct cifsFileInfo *, __u64, bool);
/* build a full path to the root of the mount */ /* build a full path to the root of the mount */
char * (*build_path_to_root)(struct smb_vol *, struct cifs_sb_info *, char * (*build_path_to_root)(struct smb_vol *, struct cifs_sb_info *,
struct cifs_tcon *); struct cifs_tcon *);

View File

@ -270,13 +270,11 @@ extern int CIFSSMBSetAttrLegacy(unsigned int xid, struct cifs_tcon *tcon,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
#endif /* possibly unneeded function */ #endif /* possibly unneeded function */
extern int CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon, extern int CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
const char *fileName, __u64 size, const char *file_name, __u64 size,
bool setAllocationSizeFlag, struct cifs_sb_info *cifs_sb, bool set_allocation);
const struct nls_table *nls_codepage,
int remap_special_chars);
extern int CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon, extern int CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
__u64 size, __u16 fileHandle, __u32 opener_pid, struct cifsFileInfo *cfile, __u64 size,
bool AllocSizeFlag); bool set_allocation);
struct cifs_unix_set_info_args { struct cifs_unix_set_info_args {
__u64 ctime; __u64 ctime;

View File

@ -5395,16 +5395,16 @@ QFSPosixRetry:
} }
/* We can not use write of zero bytes trick to /*
set file size due to need for large file support. Also note that * We can not use write of zero bytes trick to set file size due to need for
this SetPathInfo is preferred to SetFileInfo based method in next * large file support. Also note that this SetPathInfo is preferred to
routine which is only needed to work around a sharing violation bug * SetFileInfo based method in next routine which is only needed to work around
in Samba which this routine can run into */ * a sharing violation bugin Samba which this routine can run into.
*/
int int
CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon, CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
const char *fileName, __u64 size, bool SetAllocation, const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
const struct nls_table *nls_codepage, int remap) bool set_allocation)
{ {
struct smb_com_transaction2_spi_req *pSMB = NULL; struct smb_com_transaction2_spi_req *pSMB = NULL;
struct smb_com_transaction2_spi_rsp *pSMBr = NULL; struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
@ -5412,6 +5412,8 @@ CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
int name_len; int name_len;
int rc = 0; int rc = 0;
int bytes_returned = 0; int bytes_returned = 0;
int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
__u16 params, byte_count, data_count, param_offset, offset; __u16 params, byte_count, data_count, param_offset, offset;
cFYI(1, "In SetEOF"); cFYI(1, "In SetEOF");
@ -5423,14 +5425,14 @@ SetEOFRetry:
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len = name_len =
cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName, cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
PATH_MAX, nls_codepage, remap); PATH_MAX, cifs_sb->local_nls, remap);
name_len++; /* trailing null */ name_len++; /* trailing null */
name_len *= 2; name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */ } else { /* BB improve the check for buffer overruns BB */
name_len = strnlen(fileName, PATH_MAX); name_len = strnlen(file_name, PATH_MAX);
name_len++; /* trailing null */ name_len++; /* trailing null */
strncpy(pSMB->FileName, fileName, name_len); strncpy(pSMB->FileName, file_name, name_len);
} }
params = 6 + name_len; params = 6 + name_len;
data_count = sizeof(struct file_end_of_file_info); data_count = sizeof(struct file_end_of_file_info);
@ -5444,7 +5446,7 @@ SetEOFRetry:
param_offset = offsetof(struct smb_com_transaction2_spi_req, param_offset = offsetof(struct smb_com_transaction2_spi_req,
InformationLevel) - 4; InformationLevel) - 4;
offset = param_offset + params; offset = param_offset + params;
if (SetAllocation) { if (set_allocation) {
if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
pSMB->InformationLevel = pSMB->InformationLevel =
cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2); cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
@ -5491,8 +5493,8 @@ SetEOFRetry:
} }
int int
CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon, __u64 size, CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
__u16 fid, __u32 pid_of_opener, bool SetAllocation) struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
{ {
struct smb_com_transaction2_sfi_req *pSMB = NULL; struct smb_com_transaction2_sfi_req *pSMB = NULL;
struct file_end_of_file_info *parm_data; struct file_end_of_file_info *parm_data;
@ -5506,8 +5508,8 @@ CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon, __u64 size,
if (rc) if (rc)
return rc; return rc;
pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
params = 6; params = 6;
pSMB->MaxSetupCount = 0; pSMB->MaxSetupCount = 0;
@ -5536,8 +5538,8 @@ CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon, __u64 size,
+ offset); + offset);
pSMB->DataOffset = cpu_to_le16(offset); pSMB->DataOffset = cpu_to_le16(offset);
parm_data->FileSize = cpu_to_le64(size); parm_data->FileSize = cpu_to_le64(size);
pSMB->Fid = fid; pSMB->Fid = cfile->fid.netfid;
if (SetAllocation) { if (set_allocation) {
if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
pSMB->InformationLevel = pSMB->InformationLevel =
cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2); cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);

View File

@ -1883,7 +1883,8 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
struct cifsInodeInfo *cifsInode = CIFS_I(inode); struct cifsInodeInfo *cifsInode = CIFS_I(inode);
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink = NULL; struct tcon_link *tlink = NULL;
struct cifs_tcon *pTcon = NULL; struct cifs_tcon *tcon = NULL;
struct TCP_Server_Info *server;
struct cifs_io_parms io_parms; struct cifs_io_parms io_parms;
/* /*
@ -1897,19 +1898,21 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
*/ */
open_file = find_writable_file(cifsInode, true); open_file = find_writable_file(cifsInode, true);
if (open_file) { if (open_file) {
__u16 nfid = open_file->fid.netfid; tcon = tlink_tcon(open_file->tlink);
__u32 npid = open_file->pid; server = tcon->ses->server;
pTcon = tlink_tcon(open_file->tlink); if (server->ops->set_file_size)
rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid, rc = server->ops->set_file_size(xid, tcon, open_file,
npid, false); attrs->ia_size, false);
else
rc = -ENOSYS;
cifsFileInfo_put(open_file); cifsFileInfo_put(open_file);
cFYI(1, "SetFSize for attrs rc = %d", rc); cFYI(1, "SetFSize for attrs rc = %d", rc);
if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
unsigned int bytes_written; unsigned int bytes_written;
io_parms.netfid = nfid; io_parms.netfid = open_file->fid.netfid;
io_parms.pid = npid; io_parms.pid = open_file->pid;
io_parms.tcon = pTcon; io_parms.tcon = tcon;
io_parms.offset = 0; io_parms.offset = 0;
io_parms.length = attrs->ia_size; io_parms.length = attrs->ia_size;
rc = CIFSSMBWrite(xid, &io_parms, &bytes_written, rc = CIFSSMBWrite(xid, &io_parms, &bytes_written,
@ -1919,52 +1922,55 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
} else } else
rc = -EINVAL; rc = -EINVAL;
if (rc != 0) { if (!rc)
if (pTcon == NULL) { goto set_size_out;
tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink))
return PTR_ERR(tlink);
pTcon = tlink_tcon(tlink);
}
/* Set file size by pathname rather than by handle if (tcon == NULL) {
either because no valid, writeable file handle for tlink = cifs_sb_tlink(cifs_sb);
it was found or because there was an error setting if (IS_ERR(tlink))
it by handle */ return PTR_ERR(tlink);
rc = CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size, tcon = tlink_tcon(tlink);
false, cifs_sb->local_nls, server = tcon->ses->server;
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
cFYI(1, "SetEOF by path (setattrs) rc = %d", rc);
if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
__u16 netfid;
int oplock = 0;
rc = SMBLegacyOpen(xid, pTcon, full_path,
FILE_OPEN, GENERIC_WRITE,
CREATE_NOT_DIR, &netfid, &oplock, NULL,
cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
if (rc == 0) {
unsigned int bytes_written;
io_parms.netfid = netfid;
io_parms.pid = current->tgid;
io_parms.tcon = pTcon;
io_parms.offset = 0;
io_parms.length = attrs->ia_size;
rc = CIFSSMBWrite(xid, &io_parms,
&bytes_written,
NULL, NULL, 1);
cFYI(1, "wrt seteof rc %d", rc);
CIFSSMBClose(xid, pTcon, netfid);
}
}
if (tlink)
cifs_put_tlink(tlink);
} }
/*
* Set file size by pathname rather than by handle either because no
* valid, writeable file handle for it was found or because there was
* an error setting it by handle.
*/
if (server->ops->set_path_size)
rc = server->ops->set_path_size(xid, tcon, full_path,
attrs->ia_size, cifs_sb, false);
else
rc = -ENOSYS;
cFYI(1, "SetEOF by path (setattrs) rc = %d", rc);
if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
__u16 netfid;
int oplock = 0;
rc = SMBLegacyOpen(xid, tcon, full_path, FILE_OPEN,
GENERIC_WRITE, CREATE_NOT_DIR, &netfid,
&oplock, NULL, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
if (rc == 0) {
unsigned int bytes_written;
io_parms.netfid = netfid;
io_parms.pid = current->tgid;
io_parms.tcon = tcon;
io_parms.offset = 0;
io_parms.length = attrs->ia_size;
rc = CIFSSMBWrite(xid, &io_parms, &bytes_written, NULL,
NULL, 1);
cFYI(1, "wrt seteof rc %d", rc);
CIFSSMBClose(xid, tcon, netfid);
}
}
if (tlink)
cifs_put_tlink(tlink);
set_size_out:
if (rc == 0) { if (rc == 0) {
cifsInode->server_eof = attrs->ia_size; cifsInode->server_eof = attrs->ia_size;
cifs_setsize(inode, attrs->ia_size); cifs_setsize(inode, attrs->ia_size);

View File

@ -793,6 +793,8 @@ struct smb_version_operations smb1_operations = {
.query_path_info = cifs_query_path_info, .query_path_info = cifs_query_path_info,
.query_file_info = cifs_query_file_info, .query_file_info = cifs_query_file_info,
.get_srv_inum = cifs_get_srv_inum, .get_srv_inum = cifs_get_srv_inum,
.set_path_size = CIFSSMBSetEOF,
.set_file_size = CIFSSMBSetFileSize,
.build_path_to_root = cifs_build_path_to_root, .build_path_to_root = cifs_build_path_to_root,
.echo = CIFSSMBEcho, .echo = CIFSSMBEcho,
.mkdir = CIFSSMBMkDir, .mkdir = CIFSSMBMkDir,