aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/inode.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2005-09-20 23:49:16 -0400
committerSteve French <sfrench@us.ibm.com>2005-09-20 23:49:16 -0400
commite30dcf3a1905b4d2154f95db5fdfdf69691b4f0e (patch)
tree13fb11eff9f5bbbfae6eeefaf8f6a56c76885347 /fs/cifs/inode.c
parent3e87d80391c84eefceb4bda94a6363661dba4f71 (diff)
[CIFS] Add support for legacy servers part eight. Write fixes for Windows
ME, and do not set ctime unless explicitly requested with atime and/or mtime (it gets thrown away by most servers anyway as there is no way to set this via posix). Signed-off-by: Steve French (sfrench@us.ibm.com)
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r--fs/cifs/inode.c78
1 files changed, 54 insertions, 24 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 6e82e1ae03b4..ca3af4eafcb2 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1030,14 +1030,15 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1030 /* now that we found one valid file 1030 /* now that we found one valid file
1031 handle no sense continuing to loop 1031 handle no sense continuing to loop
1032 trying others, so break here */ 1032 trying others, so break here */
1033 /* if(rc == -EINVAL) { 1033 if(rc == -EINVAL) {
1034 int bytes_written; 1034 int bytes_written;
1035 rc = CIFSSMBWrite(xid, pTcon, 1035 rc = CIFSSMBWrite(xid, pTcon,
1036 nfid, 0, 1036 nfid, 0,
1037 attrs->ia_size, 1037 attrs->ia_size,
1038 &bytes_written, 1038 &bytes_written, NULL,
1039 NULL, NULL, long_op); 1039 NULL, 1 /* 45 sec */);
1040 } */ 1040 cFYI(1,("wrt seteof rc %d",rc));
1041 }
1041 break; 1042 break;
1042 } 1043 }
1043 } 1044 }
@@ -1055,14 +1056,30 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1055 cifs_sb->local_nls, 1056 cifs_sb->local_nls,
1056 cifs_sb->mnt_cifs_flags & 1057 cifs_sb->mnt_cifs_flags &
1057 CIFS_MOUNT_MAP_SPECIAL_CHR); 1058 CIFS_MOUNT_MAP_SPECIAL_CHR);
1058 cFYI(1, (" SetEOF by path (setattrs) rc = %d", rc)); 1059 cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc));
1059 /* if(rc == -EINVAL) 1060 if(rc == -EINVAL) {
1060 old_style_set_eof_via_write(xid, pTcon, 1061 __u16 netfid;
1061 full_path, 1062 int oplock = FALSE;
1062 attrs->ia_size, 1063
1063 cifs_sb->local_nls, 1064 rc = SMBLegacyOpen(xid, pTcon, full_path,
1064 cifs_sb->mnt_cifs_flags & 1065 FILE_OPEN,
1065 CIFS_MOUNT_MAP_SPECIAL_CHR);*/ 1066 SYNCHRONIZE | FILE_WRITE_ATTRIBUTES,
1067 CREATE_NOT_DIR, &netfid, &oplock,
1068 NULL, cifs_sb->local_nls,
1069 cifs_sb->mnt_cifs_flags &
1070 CIFS_MOUNT_MAP_SPECIAL_CHR);
1071 if (rc==0) {
1072 int bytes_written;
1073 rc = CIFSSMBWrite(xid, pTcon,
1074 netfid, 0,
1075 attrs->ia_size,
1076 &bytes_written, NULL,
1077 NULL, 1 /* 45 sec */);
1078 cFYI(1,("wrt seteof rc %d",rc));
1079 CIFSSMBClose(xid, pTcon, netfid);
1080 }
1081
1082 }
1066 } 1083 }
1067 1084
1068 /* Server is ok setting allocation size implicitly - no need 1085 /* Server is ok setting allocation size implicitly - no need
@@ -1075,24 +1092,22 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1075 rc = vmtruncate(direntry->d_inode, attrs->ia_size); 1092 rc = vmtruncate(direntry->d_inode, attrs->ia_size);
1076 cifs_truncate_page(direntry->d_inode->i_mapping, 1093 cifs_truncate_page(direntry->d_inode->i_mapping,
1077 direntry->d_inode->i_size); 1094 direntry->d_inode->i_size);
1078 } 1095 } else
1096 goto cifs_setattr_exit;
1079 } 1097 }
1080 if (attrs->ia_valid & ATTR_UID) { 1098 if (attrs->ia_valid & ATTR_UID) {
1081 cFYI(1, (" CIFS - UID changed to %d", attrs->ia_uid)); 1099 cFYI(1, ("UID changed to %d", attrs->ia_uid));
1082 uid = attrs->ia_uid; 1100 uid = attrs->ia_uid;
1083 /* entry->uid = cpu_to_le16(attr->ia_uid); */
1084 } 1101 }
1085 if (attrs->ia_valid & ATTR_GID) { 1102 if (attrs->ia_valid & ATTR_GID) {
1086 cFYI(1, (" CIFS - GID changed to %d", attrs->ia_gid)); 1103 cFYI(1, ("GID changed to %d", attrs->ia_gid));
1087 gid = attrs->ia_gid; 1104 gid = attrs->ia_gid;
1088 /* entry->gid = cpu_to_le16(attr->ia_gid); */
1089 } 1105 }
1090 1106
1091 time_buf.Attributes = 0; 1107 time_buf.Attributes = 0;
1092 if (attrs->ia_valid & ATTR_MODE) { 1108 if (attrs->ia_valid & ATTR_MODE) {
1093 cFYI(1, (" CIFS - Mode changed to 0x%x", attrs->ia_mode)); 1109 cFYI(1, ("Mode changed to 0x%x", attrs->ia_mode));
1094 mode = attrs->ia_mode; 1110 mode = attrs->ia_mode;
1095 /* entry->mode = cpu_to_le16(attr->ia_mode); */
1096 } 1111 }
1097 1112
1098 if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX) 1113 if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX)
@@ -1132,18 +1147,24 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1132 cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime)); 1147 cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime));
1133 } else 1148 } else
1134 time_buf.LastWriteTime = 0; 1149 time_buf.LastWriteTime = 0;
1135 1150 /* Do not set ctime explicitly unless other time
1136 if (attrs->ia_valid & ATTR_CTIME) { 1151 stamps are changed explicitly (i.e. by utime()
1152 since we would then have a mix of client and
1153 server times */
1154
1155 if (set_time && (attrs->ia_valid & ATTR_CTIME)) {
1137 set_time = TRUE; 1156 set_time = TRUE;
1138 cFYI(1, (" CIFS - CTIME changed ")); /* BB probably no need */ 1157 /* Although Samba throws this field away
1158 it may be useful to Windows - but we do
1159 not want to set ctime unless some other
1160 timestamp is changing */
1161 cFYI(1, ("CIFS - CTIME changed "));
1139 time_buf.ChangeTime = 1162 time_buf.ChangeTime =
1140 cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime)); 1163 cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime));
1141 } else 1164 } else
1142 time_buf.ChangeTime = 0; 1165 time_buf.ChangeTime = 0;
1143 1166
1144 if (set_time || time_buf.Attributes) { 1167 if (set_time || time_buf.Attributes) {
1145 /* BB what if setting one attribute fails (such as size) but
1146 time setting works? */
1147 time_buf.CreationTime = 0; /* do not change */ 1168 time_buf.CreationTime = 0; /* do not change */
1148 /* In the future we should experiment - try setting timestamps 1169 /* In the future we should experiment - try setting timestamps
1149 via Handle (SetFileInfo) instead of by path */ 1170 via Handle (SetFileInfo) instead of by path */
@@ -1182,12 +1203,21 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1182 &time_buf, cifs_sb->local_nls); */ 1203 &time_buf, cifs_sb->local_nls); */
1183 } 1204 }
1184 } 1205 }
1206 /* Even if error on time set, no sense failing the call if
1207 the server would set the time to a reasonable value anyway,
1208 and this check ensures that we are not being called from
1209 sys_utimes in which case we ought to fail the call back to
1210 the user when the server rejects the call */
1211 if((rc) && (attrs->ia_valid &&
1212 (ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE)))
1213 rc = 0;
1185 } 1214 }
1186 1215
1187 /* do not need local check to inode_check_ok since the server does 1216 /* do not need local check to inode_check_ok since the server does
1188 that */ 1217 that */
1189 if (!rc) 1218 if (!rc)
1190 rc = inode_setattr(direntry->d_inode, attrs); 1219 rc = inode_setattr(direntry->d_inode, attrs);
1220cifs_setattr_exit:
1191 kfree(full_path); 1221 kfree(full_path);
1192 FreeXid(xid); 1222 FreeXid(xid);
1193 return rc; 1223 return rc;