diff options
| author | Jeff Layton <jlayton@redhat.com> | 2008-07-23 17:28:12 -0400 |
|---|---|---|
| committer | Steve French <sfrench@us.ibm.com> | 2008-07-23 17:28:12 -0400 |
| commit | 8efdbde647f542ce0d303273df7ad4157caa03d0 (patch) | |
| tree | d672ae108f45a0288c43605b5b39652a441aa996 /fs | |
| parent | 09e50d55a9490e9b7a6fdfbf8fc078924b25ecb5 (diff) | |
[CIFS] break ATTR_SIZE changes out into their own function
Move the code that handles ATTR_SIZE changes to its own function. This
makes for a smaller function and reduces the level of indentation.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/cifs/inode.c | 151 |
1 files changed, 78 insertions, 73 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 2e904bd111c8..46e54d39461d 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
| @@ -1413,6 +1413,82 @@ out_busy: | |||
| 1413 | return -ETXTBSY; | 1413 | return -ETXTBSY; |
| 1414 | } | 1414 | } |
| 1415 | 1415 | ||
| 1416 | static int | ||
| 1417 | cifs_set_file_size(struct inode *inode, struct iattr *attrs, | ||
| 1418 | int xid, char *full_path) | ||
| 1419 | { | ||
| 1420 | int rc; | ||
| 1421 | struct cifsFileInfo *open_file; | ||
| 1422 | struct cifsInodeInfo *cifsInode = CIFS_I(inode); | ||
| 1423 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | ||
| 1424 | struct cifsTconInfo *pTcon = cifs_sb->tcon; | ||
| 1425 | |||
| 1426 | /* | ||
| 1427 | * To avoid spurious oplock breaks from server, in the case of | ||
| 1428 | * inodes that we already have open, avoid doing path based | ||
| 1429 | * setting of file size if we can do it by handle. | ||
| 1430 | * This keeps our caching token (oplock) and avoids timeouts | ||
| 1431 | * when the local oplock break takes longer to flush | ||
| 1432 | * writebehind data than the SMB timeout for the SetPathInfo | ||
| 1433 | * request would allow | ||
| 1434 | */ | ||
| 1435 | open_file = find_writable_file(cifsInode); | ||
| 1436 | if (open_file) { | ||
| 1437 | __u16 nfid = open_file->netfid; | ||
| 1438 | __u32 npid = open_file->pid; | ||
| 1439 | rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid, | ||
| 1440 | npid, false); | ||
| 1441 | atomic_dec(&open_file->wrtPending); | ||
| 1442 | cFYI(1, ("SetFSize for attrs rc = %d", rc)); | ||
| 1443 | if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { | ||
| 1444 | unsigned int bytes_written; | ||
| 1445 | rc = CIFSSMBWrite(xid, pTcon, nfid, 0, attrs->ia_size, | ||
| 1446 | &bytes_written, NULL, NULL, 1); | ||
| 1447 | cFYI(1, ("Wrt seteof rc %d", rc)); | ||
| 1448 | } | ||
| 1449 | } else | ||
| 1450 | rc = -EINVAL; | ||
| 1451 | |||
| 1452 | if (rc != 0) { | ||
| 1453 | /* Set file size by pathname rather than by handle | ||
| 1454 | either because no valid, writeable file handle for | ||
| 1455 | it was found or because there was an error setting | ||
| 1456 | it by handle */ | ||
| 1457 | rc = CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size, | ||
| 1458 | false, cifs_sb->local_nls, | ||
| 1459 | cifs_sb->mnt_cifs_flags & | ||
| 1460 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
| 1461 | cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc)); | ||
| 1462 | if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { | ||
| 1463 | __u16 netfid; | ||
| 1464 | int oplock = 0; | ||
| 1465 | |||
| 1466 | rc = SMBLegacyOpen(xid, pTcon, full_path, | ||
| 1467 | FILE_OPEN, GENERIC_WRITE, | ||
| 1468 | CREATE_NOT_DIR, &netfid, &oplock, NULL, | ||
| 1469 | cifs_sb->local_nls, | ||
| 1470 | cifs_sb->mnt_cifs_flags & | ||
| 1471 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
| 1472 | if (rc == 0) { | ||
| 1473 | unsigned int bytes_written; | ||
| 1474 | rc = CIFSSMBWrite(xid, pTcon, netfid, 0, | ||
| 1475 | attrs->ia_size, | ||
| 1476 | &bytes_written, NULL, | ||
| 1477 | NULL, 1); | ||
| 1478 | cFYI(1, ("wrt seteof rc %d", rc)); | ||
| 1479 | CIFSSMBClose(xid, pTcon, netfid); | ||
| 1480 | } | ||
| 1481 | } | ||
| 1482 | } | ||
| 1483 | |||
| 1484 | if (rc == 0) { | ||
| 1485 | rc = cifs_vmtruncate(inode, attrs->ia_size); | ||
| 1486 | cifs_truncate_page(inode->i_mapping, inode->i_size); | ||
| 1487 | } | ||
| 1488 | |||
| 1489 | return rc; | ||
| 1490 | } | ||
| 1491 | |||
| 1416 | int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | 1492 | int cifs_setattr(struct dentry *direntry, struct iattr *attrs) |
| 1417 | { | 1493 | { |
| 1418 | int xid; | 1494 | int xid; |
| @@ -1420,7 +1496,6 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
| 1420 | struct cifsTconInfo *pTcon; | 1496 | struct cifsTconInfo *pTcon; |
| 1421 | char *full_path = NULL; | 1497 | char *full_path = NULL; |
| 1422 | int rc = -EACCES; | 1498 | int rc = -EACCES; |
| 1423 | struct cifsFileInfo *open_file = NULL; | ||
| 1424 | FILE_BASIC_INFO time_buf; | 1499 | FILE_BASIC_INFO time_buf; |
| 1425 | bool set_time = false; | 1500 | bool set_time = false; |
| 1426 | bool set_dosattr = false; | 1501 | bool set_dosattr = false; |
| @@ -1472,78 +1547,8 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
| 1472 | } | 1547 | } |
| 1473 | 1548 | ||
| 1474 | if (attrs->ia_valid & ATTR_SIZE) { | 1549 | if (attrs->ia_valid & ATTR_SIZE) { |
| 1475 | /* To avoid spurious oplock breaks from server, in the case of | 1550 | rc = cifs_set_file_size(inode, attrs, xid, full_path); |
| 1476 | inodes that we already have open, avoid doing path based | 1551 | if (rc != 0) |
| 1477 | setting of file size if we can do it by handle. | ||
| 1478 | This keeps our caching token (oplock) and avoids timeouts | ||
| 1479 | when the local oplock break takes longer to flush | ||
| 1480 | writebehind data than the SMB timeout for the SetPathInfo | ||
| 1481 | request would allow */ | ||
| 1482 | |||
| 1483 | open_file = find_writable_file(cifsInode); | ||
| 1484 | if (open_file) { | ||
| 1485 | __u16 nfid = open_file->netfid; | ||
| 1486 | __u32 npid = open_file->pid; | ||
| 1487 | rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, | ||
| 1488 | nfid, npid, false); | ||
| 1489 | atomic_dec(&open_file->wrtPending); | ||
| 1490 | cFYI(1, ("SetFSize for attrs rc = %d", rc)); | ||
| 1491 | if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { | ||
| 1492 | unsigned int bytes_written; | ||
| 1493 | rc = CIFSSMBWrite(xid, pTcon, | ||
| 1494 | nfid, 0, attrs->ia_size, | ||
| 1495 | &bytes_written, NULL, NULL, | ||
| 1496 | 1 /* 45 seconds */); | ||
| 1497 | cFYI(1, ("Wrt seteof rc %d", rc)); | ||
| 1498 | } | ||
| 1499 | } else | ||
| 1500 | rc = -EINVAL; | ||
| 1501 | |||
| 1502 | if (rc != 0) { | ||
| 1503 | /* Set file size by pathname rather than by handle | ||
| 1504 | either because no valid, writeable file handle for | ||
| 1505 | it was found or because there was an error setting | ||
| 1506 | it by handle */ | ||
| 1507 | rc = CIFSSMBSetEOF(xid, pTcon, full_path, | ||
| 1508 | attrs->ia_size, false, | ||
| 1509 | cifs_sb->local_nls, | ||
| 1510 | cifs_sb->mnt_cifs_flags & | ||
| 1511 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
| 1512 | cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc)); | ||
| 1513 | if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { | ||
| 1514 | __u16 netfid; | ||
| 1515 | int oplock = 0; | ||
| 1516 | |||
| 1517 | rc = SMBLegacyOpen(xid, pTcon, full_path, | ||
| 1518 | FILE_OPEN, GENERIC_WRITE, | ||
| 1519 | CREATE_NOT_DIR, &netfid, &oplock, | ||
| 1520 | NULL, cifs_sb->local_nls, | ||
| 1521 | cifs_sb->mnt_cifs_flags & | ||
| 1522 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
| 1523 | if (rc == 0) { | ||
| 1524 | unsigned int bytes_written; | ||
| 1525 | rc = CIFSSMBWrite(xid, pTcon, | ||
| 1526 | netfid, 0, | ||
| 1527 | attrs->ia_size, | ||
| 1528 | &bytes_written, NULL, | ||
| 1529 | NULL, 1 /* 45 sec */); | ||
| 1530 | cFYI(1, ("wrt seteof rc %d", rc)); | ||
| 1531 | CIFSSMBClose(xid, pTcon, netfid); | ||
| 1532 | } | ||
| 1533 | |||
| 1534 | } | ||
| 1535 | } | ||
| 1536 | |||
| 1537 | /* Server is ok setting allocation size implicitly - no need | ||
| 1538 | to call: | ||
| 1539 | CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size, true, | ||
| 1540 | cifs_sb->local_nls); | ||
| 1541 | */ | ||
| 1542 | |||
| 1543 | if (rc == 0) { | ||
| 1544 | rc = cifs_vmtruncate(inode, attrs->ia_size); | ||
| 1545 | cifs_truncate_page(inode->i_mapping, inode->i_size); | ||
| 1546 | } else | ||
| 1547 | goto cifs_setattr_exit; | 1552 | goto cifs_setattr_exit; |
| 1548 | } | 1553 | } |
| 1549 | 1554 | ||
