]> err.no Git - linux-2.6/blobdiff - fs/cifs/inode.c
Rename CIFSSMBSetFileTimes to CIFSSMBSetFileInfo and add PID arg
[linux-2.6] / fs / cifs / inode.c
index 2e904bd111c8f5996045302fe66bfe99c5753bf9..d952914dfc4ce4267753b95043629d105ed6d61a 100644 (file)
@@ -737,7 +737,7 @@ psx_del_no_retry:
                        /* ATTRS set to normal clears r/o bit */
                        pinfo_buf->Attributes = cpu_to_le32(ATTR_NORMAL);
                        if (!(pTcon->ses->flags & CIFS_SES_NT4))
-                               rc = CIFSSMBSetTimes(xid, pTcon, full_path,
+                               rc = CIFSSMBSetPathInfo(xid, pTcon, full_path,
                                                     pinfo_buf,
                                                     cifs_sb->local_nls,
                                                     cifs_sb->mnt_cifs_flags &
@@ -767,9 +767,10 @@ psx_del_no_retry:
                                                 cifs_sb->mnt_cifs_flags &
                                                    CIFS_MOUNT_MAP_SPECIAL_CHR);
                                if (rc == 0) {
-                                       rc = CIFSSMBSetFileTimes(xid, pTcon,
-                                                                pinfo_buf,
-                                                                netfid);
+                                       rc = CIFSSMBSetFileInfo(xid, pTcon,
+                                                               pinfo_buf,
+                                                               netfid,
+                                                               current->tgid);
                                        CIFSSMBClose(xid, pTcon, netfid);
                                }
                        }
@@ -986,30 +987,31 @@ mkdir_get_info:
                                direntry->d_inode->i_nlink = 2;
                mode &= ~current->fs->umask;
                if (pTcon->unix_ext) {
+                       struct cifs_unix_set_info_args args = {
+                               .mode   = mode,
+                               .ctime  = NO_CHANGE_64,
+                               .atime  = NO_CHANGE_64,
+                               .mtime  = NO_CHANGE_64,
+                               .device = 0,
+                       };
                        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
-                               CIFSSMBUnixSetPerms(xid, pTcon, full_path,
-                                                   mode,
-                                                   (__u64)current->fsuid,
-                                                   (__u64)current->fsgid,
-                                                   0 /* dev_t */,
-                                                   cifs_sb->local_nls,
-                                                   cifs_sb->mnt_cifs_flags &
-                                                   CIFS_MOUNT_MAP_SPECIAL_CHR);
+                               args.uid = (__u64)current->fsuid;
+                               args.gid = (__u64)current->fsgid;
                        } else {
-                               CIFSSMBUnixSetPerms(xid, pTcon, full_path,
-                                                   mode, (__u64)-1,
-                                                   (__u64)-1, 0 /* dev_t */,
-                                                   cifs_sb->local_nls,
-                                                   cifs_sb->mnt_cifs_flags &
-                                                   CIFS_MOUNT_MAP_SPECIAL_CHR);
+                               args.uid = NO_CHANGE_64;
+                               args.gid = NO_CHANGE_64;
                        }
+                       CIFSSMBUnixSetInfo(xid, pTcon, full_path, &args,
+                                           cifs_sb->local_nls,
+                                           cifs_sb->mnt_cifs_flags &
+                                           CIFS_MOUNT_MAP_SPECIAL_CHR);
                } else {
                        if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&
                            (mode & S_IWUGO) == 0) {
                                FILE_BASIC_INFO pInfo;
                                memset(&pInfo, 0, sizeof(pInfo));
                                pInfo.Attributes = cpu_to_le32(ATTR_READONLY);
-                               CIFSSMBSetTimes(xid, pTcon, full_path,
+                               CIFSSMBSetPathInfo(xid, pTcon, full_path,
                                                &pInfo, cifs_sb->local_nls,
                                                cifs_sb->mnt_cifs_flags &
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -1310,10 +1312,11 @@ int cifs_revalidate(struct dentry *direntry)
 /*             if (S_ISDIR(direntry->d_inode->i_mode))
                        shrink_dcache_parent(direntry); */
                if (S_ISREG(direntry->d_inode->i_mode)) {
-                       if (direntry->d_inode->i_mapping)
+                       if (direntry->d_inode->i_mapping) {
                                wbrc = filemap_fdatawait(direntry->d_inode->i_mapping);
                                if (wbrc)
                                        CIFS_I(direntry->d_inode)->write_behind_rc = wbrc;
+                       }
                        /* may eventually have to do this for open files too */
                        if (list_empty(&(cifsInode->openFileList))) {
                                /* changed on server - flush read ahead pages */
@@ -1413,6 +1416,82 @@ out_busy:
        return -ETXTBSY;
 }
 
+static int
+cifs_set_file_size(struct inode *inode, struct iattr *attrs,
+                  int xid, char *full_path)
+{
+       int rc;
+       struct cifsFileInfo *open_file;
+       struct cifsInodeInfo *cifsInode = CIFS_I(inode);
+       struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+       struct cifsTconInfo *pTcon = cifs_sb->tcon;
+
+       /*
+        * To avoid spurious oplock breaks from server, in the case of
+        * inodes that we already have open, avoid doing path based
+        * setting of file size if we can do it by handle.
+        * This keeps our caching token (oplock) and avoids timeouts
+        * when the local oplock break takes longer to flush
+        * writebehind data than the SMB timeout for the SetPathInfo
+        * request would allow
+        */
+       open_file = find_writable_file(cifsInode);
+       if (open_file) {
+               __u16 nfid = open_file->netfid;
+               __u32 npid = open_file->pid;
+               rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid,
+                                       npid, false);
+               atomic_dec(&open_file->wrtPending);
+               cFYI(1, ("SetFSize for attrs rc = %d", rc));
+               if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
+                       unsigned int bytes_written;
+                       rc = CIFSSMBWrite(xid, pTcon, nfid, 0, attrs->ia_size,
+                                         &bytes_written, NULL, NULL, 1);
+                       cFYI(1, ("Wrt seteof rc %d", rc));
+               }
+       } else
+               rc = -EINVAL;
+
+       if (rc != 0) {
+               /* 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,
+                                  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;
+                               rc = CIFSSMBWrite(xid, pTcon, netfid, 0,
+                                                 attrs->ia_size,
+                                                 &bytes_written, NULL,
+                                                 NULL, 1);
+                               cFYI(1, ("wrt seteof rc %d", rc));
+                               CIFSSMBClose(xid, pTcon, netfid);
+                       }
+               }
+       }
+
+       if (rc == 0) {
+               rc = cifs_vmtruncate(inode, attrs->ia_size);
+               cifs_truncate_page(inode->i_mapping, inode->i_size);
+       }
+
+       return rc;
+}
+
 int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
 {
        int xid;
@@ -1420,13 +1499,12 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
        struct cifsTconInfo *pTcon;
        char *full_path = NULL;
        int rc = -EACCES;
-       struct cifsFileInfo *open_file = NULL;
        FILE_BASIC_INFO time_buf;
        bool set_time = false;
        bool set_dosattr = false;
-       __u64 mode = 0xFFFFFFFFFFFFFFFFULL;
-       __u64 uid = 0xFFFFFFFFFFFFFFFFULL;
-       __u64 gid = 0xFFFFFFFFFFFFFFFFULL;
+       __u64 mode = NO_CHANGE_64;
+       __u64 uid = NO_CHANGE_64;
+       __u64 gid = NO_CHANGE_64;
        struct cifsInodeInfo *cifsInode;
        struct inode *inode = direntry->d_inode;
 
@@ -1472,78 +1550,8 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
        }
 
        if (attrs->ia_valid & ATTR_SIZE) {
-               /* To avoid spurious oplock breaks from server, in the case of
-                  inodes that we already have open, avoid doing path based
-                  setting of file size if we can do it by handle.
-                  This keeps our caching token (oplock) and avoids timeouts
-                  when the local oplock break takes longer to flush
-                  writebehind data than the SMB timeout for the SetPathInfo
-                  request would allow */
-
-               open_file = find_writable_file(cifsInode);
-               if (open_file) {
-                       __u16 nfid = open_file->netfid;
-                       __u32 npid = open_file->pid;
-                       rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size,
-                                               nfid, npid, false);
-                       atomic_dec(&open_file->wrtPending);
-                       cFYI(1, ("SetFSize for attrs rc = %d", rc));
-                       if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
-                               unsigned int bytes_written;
-                               rc = CIFSSMBWrite(xid, pTcon,
-                                                 nfid, 0, attrs->ia_size,
-                                                 &bytes_written, NULL, NULL,
-                                                 1 /* 45 seconds */);
-                               cFYI(1, ("Wrt seteof rc %d", rc));
-                       }
-               } else
-                       rc = -EINVAL;
-
-               if (rc != 0) {
-                       /* 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,
-                                          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;
-                                       rc = CIFSSMBWrite(xid, pTcon,
-                                                       netfid, 0,
-                                                       attrs->ia_size,
-                                                       &bytes_written, NULL,
-                                                       NULL, 1 /* 45 sec */);
-                                       cFYI(1, ("wrt seteof rc %d", rc));
-                                       CIFSSMBClose(xid, pTcon, netfid);
-                               }
-
-                       }
-               }
-
-               /* Server is ok setting allocation size implicitly - no need
-                  to call:
-               CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size, true,
-                        cifs_sb->local_nls);
-                  */
-
-               if (rc == 0) {
-                       rc = cifs_vmtruncate(inode, attrs->ia_size);
-                       cifs_truncate_page(inode->i_mapping, inode->i_size);
-               } else
+               rc = cifs_set_file_size(inode, attrs, xid, full_path);
+               if (rc != 0)
                        goto cifs_setattr_exit;
        }
 
@@ -1580,12 +1588,21 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
        }
 
        if ((pTcon->unix_ext)
-           && (attrs->ia_valid & (ATTR_MODE | ATTR_GID | ATTR_UID)))
-               rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, uid, gid,
-                                        0 /* dev_t */, cifs_sb->local_nls,
-                                        cifs_sb->mnt_cifs_flags &
+           && (attrs->ia_valid & (ATTR_MODE | ATTR_GID | ATTR_UID))) {
+               struct cifs_unix_set_info_args args = {
+                       .mode   = mode,
+                       .uid    = uid,
+                       .gid    = gid,
+                       .ctime  = NO_CHANGE_64,
+                       .atime  = NO_CHANGE_64,
+                       .mtime  = NO_CHANGE_64,
+                       .device = 0,
+               };
+               rc = CIFSSMBUnixSetInfo(xid, pTcon, full_path, &args,
+                                       cifs_sb->local_nls,
+                                       cifs_sb->mnt_cifs_flags &
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
-       else if (attrs->ia_valid & ATTR_MODE) {
+       else if (attrs->ia_valid & ATTR_MODE) {
                rc = 0;
 #ifdef CONFIG_CIFS_EXPERIMENTAL
                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
@@ -1664,8 +1681,8 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
                /* In the future we should experiment - try setting timestamps
                   via Handle (SetFileInfo) instead of by path */
                if (!(pTcon->ses->flags & CIFS_SES_NT4))
-                       rc = CIFSSMBSetTimes(xid, pTcon, full_path, &time_buf,
-                                            cifs_sb->local_nls,
+                       rc = CIFSSMBSetPathInfo(xid, pTcon, full_path,
+                                            &time_buf, cifs_sb->local_nls,
                                             cifs_sb->mnt_cifs_flags &
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
                else
@@ -1686,8 +1703,8 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
                                         cifs_sb->mnt_cifs_flags &
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
                        if (rc == 0) {
-                               rc = CIFSSMBSetFileTimes(xid, pTcon, &time_buf,
-                                                        netfid);
+                               rc = CIFSSMBSetFileInfo(xid, pTcon, &time_buf,
+                                                        netfid, current->tgid);
                                CIFSSMBClose(xid, pTcon, netfid);
                        } else {
                        /* BB For even older servers we could convert time_buf