diff options
author | Steve French <sfrench@us.ibm.com> | 2005-08-30 23:58:07 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2005-08-30 23:58:07 -0400 |
commit | 1c9551878c4629ca78dfe12ed23b9dc8d97770cc (patch) | |
tree | 4d9df5ad22d88dd0f62ab9f44d761f1df6a77d55 /fs/cifs/file.c | |
parent | cb8be64084e6294fcb9e558188fe104050b94f0b (diff) |
[CIFS] Add support for legacy servers part 4
Fix WriteX support for old servers which do not support large
files.
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r-- | fs/cifs/file.c | 66 |
1 files changed, 48 insertions, 18 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index ef455dda0473..b6c303f6373f 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -1183,11 +1183,16 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, | |||
1183 | char *smb_read_data; | 1183 | char *smb_read_data; |
1184 | char __user *current_offset; | 1184 | char __user *current_offset; |
1185 | struct smb_com_read_rsp *pSMBr; | 1185 | struct smb_com_read_rsp *pSMBr; |
1186 | int use_old_read = FALSE; | ||
1186 | 1187 | ||
1187 | xid = GetXid(); | 1188 | xid = GetXid(); |
1188 | cifs_sb = CIFS_SB(file->f_dentry->d_sb); | 1189 | cifs_sb = CIFS_SB(file->f_dentry->d_sb); |
1189 | pTcon = cifs_sb->tcon; | 1190 | pTcon = cifs_sb->tcon; |
1190 | 1191 | ||
1192 | if(pTcon->ses) | ||
1193 | if((pTcon->ses->capabilities & CAP_LARGE_FILES) == 0) | ||
1194 | use_old_read = TRUE; | ||
1195 | |||
1191 | if (file->private_data == NULL) { | 1196 | if (file->private_data == NULL) { |
1192 | FreeXid(xid); | 1197 | FreeXid(xid); |
1193 | return -EBADF; | 1198 | return -EBADF; |
@@ -1212,16 +1217,21 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, | |||
1212 | if (rc != 0) | 1217 | if (rc != 0) |
1213 | break; | 1218 | break; |
1214 | } | 1219 | } |
1215 | 1220 | if(use_old_read) | |
1216 | rc = CIFSSMBRead(xid, pTcon, | ||
1217 | open_file->netfid, | ||
1218 | current_read_size, *poffset, | ||
1219 | &bytes_read, &smb_read_data); | ||
1220 | if(rc == -EINVAL) { | ||
1221 | rc = SMBLegacyRead(xid, pTcon, | 1221 | rc = SMBLegacyRead(xid, pTcon, |
1222 | open_file->netfid, | 1222 | open_file->netfid, |
1223 | current_read_size, *poffset, | 1223 | current_read_size, *poffset, |
1224 | &bytes_read, &smb_read_data); | 1224 | &bytes_read, &smb_read_data); |
1225 | else { | ||
1226 | rc = CIFSSMBRead(xid, pTcon, | ||
1227 | open_file->netfid, | ||
1228 | current_read_size, *poffset, | ||
1229 | &bytes_read, &smb_read_data); | ||
1230 | if(rc == -EINVAL) { | ||
1231 | use_old_read = TRUE; | ||
1232 | rc = -EAGAIN; | ||
1233 | continue; | ||
1234 | } | ||
1225 | } | 1235 | } |
1226 | pSMBr = (struct smb_com_read_rsp *)smb_read_data; | 1236 | pSMBr = (struct smb_com_read_rsp *)smb_read_data; |
1227 | if (copy_to_user(current_offset, | 1237 | if (copy_to_user(current_offset, |
@@ -1266,6 +1276,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, | |||
1266 | int xid; | 1276 | int xid; |
1267 | char *current_offset; | 1277 | char *current_offset; |
1268 | struct cifsFileInfo *open_file; | 1278 | struct cifsFileInfo *open_file; |
1279 | int use_old_read = FALSE; | ||
1269 | 1280 | ||
1270 | xid = GetXid(); | 1281 | xid = GetXid(); |
1271 | cifs_sb = CIFS_SB(file->f_dentry->d_sb); | 1282 | cifs_sb = CIFS_SB(file->f_dentry->d_sb); |
@@ -1276,6 +1287,9 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, | |||
1276 | return -EBADF; | 1287 | return -EBADF; |
1277 | } | 1288 | } |
1278 | open_file = (struct cifsFileInfo *)file->private_data; | 1289 | open_file = (struct cifsFileInfo *)file->private_data; |
1290 | if(pTcon->ses) | ||
1291 | if((pTcon->ses->capabilities & CAP_LARGE_FILES) == 0) | ||
1292 | use_old_read = TRUE; | ||
1279 | 1293 | ||
1280 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) | 1294 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) |
1281 | cFYI(1, ("attempting read on write only file instance")); | 1295 | cFYI(1, ("attempting read on write only file instance")); |
@@ -1294,16 +1308,23 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, | |||
1294 | if (rc != 0) | 1308 | if (rc != 0) |
1295 | break; | 1309 | break; |
1296 | } | 1310 | } |
1297 | 1311 | if(use_old_read) | |
1298 | rc = CIFSSMBRead(xid, pTcon, | ||
1299 | open_file->netfid, | ||
1300 | current_read_size, *poffset, | ||
1301 | &bytes_read, ¤t_offset); | ||
1302 | if(rc == -EINVAL) { | ||
1303 | rc = SMBLegacyRead(xid, pTcon, | 1312 | rc = SMBLegacyRead(xid, pTcon, |
1313 | open_file->netfid, | ||
1314 | current_read_size, *poffset, | ||
1315 | &bytes_read, ¤t_offset); | ||
1316 | else { | ||
1317 | rc = CIFSSMBRead(xid, pTcon, | ||
1304 | open_file->netfid, | 1318 | open_file->netfid, |
1305 | current_read_size, *poffset, | 1319 | current_read_size, *poffset, |
1306 | &bytes_read, ¤t_offset); | 1320 | &bytes_read, ¤t_offset); |
1321 | /* check if server disavows support for | ||
1322 | 64 bit offsets */ | ||
1323 | if(rc == -EINVAL) { | ||
1324 | rc = -EAGAIN; | ||
1325 | use_old_read = TRUE; | ||
1326 | continue; | ||
1327 | } | ||
1307 | } | 1328 | } |
1308 | } | 1329 | } |
1309 | if (rc || (bytes_read == 0)) { | 1330 | if (rc || (bytes_read == 0)) { |
@@ -1402,6 +1423,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1402 | struct smb_com_read_rsp *pSMBr; | 1423 | struct smb_com_read_rsp *pSMBr; |
1403 | struct pagevec lru_pvec; | 1424 | struct pagevec lru_pvec; |
1404 | struct cifsFileInfo *open_file; | 1425 | struct cifsFileInfo *open_file; |
1426 | int use_old_read = FALSE; | ||
1405 | 1427 | ||
1406 | xid = GetXid(); | 1428 | xid = GetXid(); |
1407 | if (file->private_data == NULL) { | 1429 | if (file->private_data == NULL) { |
@@ -1411,7 +1433,9 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1411 | open_file = (struct cifsFileInfo *)file->private_data; | 1433 | open_file = (struct cifsFileInfo *)file->private_data; |
1412 | cifs_sb = CIFS_SB(file->f_dentry->d_sb); | 1434 | cifs_sb = CIFS_SB(file->f_dentry->d_sb); |
1413 | pTcon = cifs_sb->tcon; | 1435 | pTcon = cifs_sb->tcon; |
1414 | 1436 | if(pTcon->ses) | |
1437 | if((pTcon->ses->capabilities & CAP_LARGE_FILES) == 0) | ||
1438 | use_old_read = TRUE; | ||
1415 | pagevec_init(&lru_pvec, 0); | 1439 | pagevec_init(&lru_pvec, 0); |
1416 | 1440 | ||
1417 | for (i = 0; i < num_pages; ) { | 1441 | for (i = 0; i < num_pages; ) { |
@@ -1457,15 +1481,21 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1457 | break; | 1481 | break; |
1458 | } | 1482 | } |
1459 | 1483 | ||
1460 | rc = CIFSSMBRead(xid, pTcon, | 1484 | if(use_old_read) |
1461 | open_file->netfid, | ||
1462 | read_size, offset, | ||
1463 | &bytes_read, &smb_read_data); | ||
1464 | if (rc == -EINVAL) { | ||
1465 | rc = SMBLegacyRead(xid, pTcon, | 1485 | rc = SMBLegacyRead(xid, pTcon, |
1466 | open_file->netfid, | 1486 | open_file->netfid, |
1467 | read_size, offset, | 1487 | read_size, offset, |
1468 | &bytes_read, &smb_read_data); | 1488 | &bytes_read, &smb_read_data); |
1489 | else { | ||
1490 | rc = CIFSSMBRead(xid, pTcon, | ||
1491 | open_file->netfid, | ||
1492 | read_size, offset, | ||
1493 | &bytes_read, &smb_read_data); | ||
1494 | if(rc == -EINVAL) { | ||
1495 | use_old_read = TRUE; | ||
1496 | rc = -EAGAIN; | ||
1497 | continue; | ||
1498 | } | ||
1469 | } | 1499 | } |
1470 | 1500 | ||
1471 | /* BB more RC checks ? */ | 1501 | /* BB more RC checks ? */ |