aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2008-07-23 17:28:12 -0400
committerSteve French <sfrench@us.ibm.com>2008-07-23 17:28:12 -0400
commit8efdbde647f542ce0d303273df7ad4157caa03d0 (patch)
treed672ae108f45a0288c43605b5b39652a441aa996
parent09e50d55a9490e9b7a6fdfbf8fc078924b25ecb5 (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>
-rw-r--r--fs/cifs/inode.c151
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
1416static int
1417cifs_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
1416int cifs_setattr(struct dentry *direntry, struct iattr *attrs) 1492int 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