CIFS: Move set_file_size to ops struct
authorPavel Shilovsky <pshilovsky@samba.org>
Tue, 18 Sep 2012 23:20:31 +0000 (16:20 -0700)
committerSteve French <smfrench@gmail.com>
Tue, 25 Sep 2012 02:46:29 +0000 (21:46 -0500)
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org>
Signed-off-by: Steve French <smfrench@gmail.com>
fs/cifs/cifsglob.h
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/inode.c
fs/cifs/smb1ops.c

index 8595d498ad80d9357308ed70955440c80ff1ec14..803c21218633309bdce1433d8b07acb98fe0ea9e 100644 (file)
@@ -252,6 +252,12 @@ struct smb_version_operations {
        int (*get_srv_inum)(const unsigned int, struct cifs_tcon *,
                            struct cifs_sb_info *, const char *,
                            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 */
        char * (*build_path_to_root)(struct smb_vol *, struct cifs_sb_info *,
                                     struct cifs_tcon *);
index 3c50555c7735d5a8723b4e33f9b07ea22e3fd423..3d99fe9afccc7141d7a38d5982fe066470fb4700 100644 (file)
@@ -270,13 +270,11 @@ extern int CIFSSMBSetAttrLegacy(unsigned int xid, struct cifs_tcon *tcon,
                        const struct nls_table *nls_codepage);
 #endif /* possibly unneeded function */
 extern int CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
-                       const char *fileName, __u64 size,
-                       bool setAllocationSizeFlag,
-                       const struct nls_table *nls_codepage,
-                       int remap_special_chars);
+                        const char *file_name, __u64 size,
+                        struct cifs_sb_info *cifs_sb, bool set_allocation);
 extern int CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
-                        __u64 size, __u16 fileHandle, __u32 opener_pid,
-                       bool AllocSizeFlag);
+                             struct cifsFileInfo *cfile, __u64 size,
+                             bool set_allocation);
 
 struct cifs_unix_set_info_args {
        __u64   ctime;
index eb3d2cf76e6e75bcf5ad32c30f15405540b43d3d..c4f43cf671dc2f3bd5b14649f4647d1b94f73608 100644 (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
-   this SetPathInfo is preferred to SetFileInfo based method in next
-   routine which is only needed to work around a sharing violation bug
-   in Samba which this routine can run into */
-
+/*
+ * We can not use write of zero bytes trick to set file size due to need for
+ * large file support. Also note that this SetPathInfo is preferred to
+ * SetFileInfo based method in next routine which is only needed to work around
+ * a sharing violation bugin Samba which this routine can run into.
+ */
 int
 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
-             const char *fileName, __u64 size, bool SetAllocation,
-             const struct nls_table *nls_codepage, int remap)
+             const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
+             bool set_allocation)
 {
        struct smb_com_transaction2_spi_req *pSMB = 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 rc = 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;
 
        cFYI(1, "In SetEOF");
@@ -5423,14 +5425,14 @@ SetEOFRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
-                                      PATH_MAX, nls_codepage, remap);
+                   cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
+                                      PATH_MAX, cifs_sb->local_nls, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
        } 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 */
-               strncpy(pSMB->FileName, fileName, name_len);
+               strncpy(pSMB->FileName, file_name, name_len);
        }
        params = 6 + name_len;
        data_count = sizeof(struct file_end_of_file_info);
@@ -5444,7 +5446,7 @@ SetEOFRetry:
        param_offset = offsetof(struct smb_com_transaction2_spi_req,
                                InformationLevel) - 4;
        offset = param_offset + params;
-       if (SetAllocation) {
+       if (set_allocation) {
                if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
                        pSMB->InformationLevel =
                                cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
@@ -5491,8 +5493,8 @@ SetEOFRetry:
 }
 
 int
-CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon, __u64 size,
-                  __u16 fid, __u32 pid_of_opener, bool SetAllocation)
+CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
+                  struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
 {
        struct smb_com_transaction2_sfi_req *pSMB  = NULL;
        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)
                return rc;
 
-       pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
-       pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
+       pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
+       pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
 
        params = 6;
        pSMB->MaxSetupCount = 0;
@@ -5536,8 +5538,8 @@ CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon, __u64 size,
                                + offset);
        pSMB->DataOffset = cpu_to_le16(offset);
        parm_data->FileSize = cpu_to_le64(size);
-       pSMB->Fid = fid;
-       if (SetAllocation) {
+       pSMB->Fid = cfile->fid.netfid;
+       if (set_allocation) {
                if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
                        pSMB->InformationLevel =
                                cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
index 2f3235f08c3f7c34121cfc18efab419a728109a7..85e1b0a405a8d0ef1b6839a4753182838969c829 100644 (file)
@@ -1883,7 +1883,8 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
        struct cifsInodeInfo *cifsInode = CIFS_I(inode);
        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
        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;
 
        /*
@@ -1897,19 +1898,21 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
         */
        open_file = find_writable_file(cifsInode, true);
        if (open_file) {
-               __u16 nfid = open_file->fid.netfid;
-               __u32 npid = open_file->pid;
-               pTcon = tlink_tcon(open_file->tlink);
-               rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid,
-                                       npid, false);
+               tcon = tlink_tcon(open_file->tlink);
+               server = tcon->ses->server;
+               if (server->ops->set_file_size)
+                       rc = server->ops->set_file_size(xid, tcon, open_file,
+                                                       attrs->ia_size, false);
+               else
+                       rc = -ENOSYS;
                cifsFileInfo_put(open_file);
                cFYI(1, "SetFSize for attrs rc = %d", rc);
                if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
                        unsigned int bytes_written;
 
-                       io_parms.netfid = nfid;
-                       io_parms.pid = npid;
-                       io_parms.tcon = pTcon;
+                       io_parms.netfid = open_file->fid.netfid;
+                       io_parms.pid = open_file->pid;
+                       io_parms.tcon = tcon;
                        io_parms.offset = 0;
                        io_parms.length = attrs->ia_size;
                        rc = CIFSSMBWrite(xid, &io_parms, &bytes_written,
@@ -1919,52 +1922,55 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
        } else
                rc = -EINVAL;
 
-       if (rc != 0) {
-               if (pTcon == NULL) {
-                       tlink = cifs_sb_tlink(cifs_sb);
-                       if (IS_ERR(tlink))
-                               return PTR_ERR(tlink);
-                       pTcon = tlink_tcon(tlink);
-               }
+       if (!rc)
+               goto set_size_out;
 
-               /* 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 */
-               rc = CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size,
-                                  false, cifs_sb->local_nls,
+       if (tcon == NULL) {
+               tlink = cifs_sb_tlink(cifs_sb);
+               if (IS_ERR(tlink))
+                       return PTR_ERR(tlink);
+               tcon = tlink_tcon(tlink);
+               server = tcon->ses->server;
+       }
+
+       /*
+        * 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);
-               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);
-                       }
+                                               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);
        }
+       if (tlink)
+               cifs_put_tlink(tlink);
 
+set_size_out:
        if (rc == 0) {
                cifsInode->server_eof = attrs->ia_size;
                cifs_setsize(inode, attrs->ia_size);
index e5d63444f0ff2354de1a3d5f47efe2fc193753f4..b73d2750296d22754c76bdaef96a1821582f969c 100644 (file)
@@ -793,6 +793,8 @@ struct smb_version_operations smb1_operations = {
        .query_path_info = cifs_query_path_info,
        .query_file_info = cifs_query_file_info,
        .get_srv_inum = cifs_get_srv_inum,
+       .set_path_size = CIFSSMBSetEOF,
+       .set_file_size = CIFSSMBSetFileSize,
        .build_path_to_root = cifs_build_path_to_root,
        .echo = CIFSSMBEcho,
        .mkdir = CIFSSMBMkDir,