diff options
author | Pavel Shilovsky <pshilovsky@samba.org> | 2012-09-18 19:20:30 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2012-09-24 22:46:28 -0400 |
commit | 8ceb984379462f94bdebef3288d569c6e1f912ea (patch) | |
tree | 6aa83326bf1b54ba9e464b886c0749349506033c /fs/cifs/inode.c | |
parent | 3c1bf7e48e9e463b65b1b90da4500a93dd2b27a7 (diff) |
CIFS: Move rename to ops struct
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org>
Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r-- | fs/cifs/inode.c | 92 |
1 files changed, 48 insertions, 44 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index c6f6b02cf3b5..2f3235f08c3f 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -1512,29 +1512,32 @@ rmdir_exit: | |||
1512 | } | 1512 | } |
1513 | 1513 | ||
1514 | static int | 1514 | static int |
1515 | cifs_do_rename(unsigned int xid, struct dentry *from_dentry, | 1515 | cifs_do_rename(const unsigned int xid, struct dentry *from_dentry, |
1516 | const char *fromPath, struct dentry *to_dentry, | 1516 | const char *from_path, struct dentry *to_dentry, |
1517 | const char *toPath) | 1517 | const char *to_path) |
1518 | { | 1518 | { |
1519 | struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb); | 1519 | struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb); |
1520 | struct tcon_link *tlink; | 1520 | struct tcon_link *tlink; |
1521 | struct cifs_tcon *pTcon; | 1521 | struct cifs_tcon *tcon; |
1522 | struct TCP_Server_Info *server; | ||
1522 | __u16 srcfid; | 1523 | __u16 srcfid; |
1523 | int oplock, rc; | 1524 | int oplock, rc; |
1524 | 1525 | ||
1525 | tlink = cifs_sb_tlink(cifs_sb); | 1526 | tlink = cifs_sb_tlink(cifs_sb); |
1526 | if (IS_ERR(tlink)) | 1527 | if (IS_ERR(tlink)) |
1527 | return PTR_ERR(tlink); | 1528 | return PTR_ERR(tlink); |
1528 | pTcon = tlink_tcon(tlink); | 1529 | tcon = tlink_tcon(tlink); |
1530 | server = tcon->ses->server; | ||
1531 | |||
1532 | if (!server->ops->rename) | ||
1533 | return -ENOSYS; | ||
1529 | 1534 | ||
1530 | /* try path-based rename first */ | 1535 | /* try path-based rename first */ |
1531 | rc = CIFSSMBRename(xid, pTcon, fromPath, toPath, cifs_sb->local_nls, | 1536 | rc = server->ops->rename(xid, tcon, from_path, to_path, cifs_sb); |
1532 | cifs_sb->mnt_cifs_flags & | ||
1533 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
1534 | 1537 | ||
1535 | /* | 1538 | /* |
1536 | * don't bother with rename by filehandle unless file is busy and | 1539 | * Don't bother with rename by filehandle unless file is busy and |
1537 | * source Note that cross directory moves do not work with | 1540 | * source. Note that cross directory moves do not work with |
1538 | * rename by filehandle to various Windows servers. | 1541 | * rename by filehandle to various Windows servers. |
1539 | */ | 1542 | */ |
1540 | if (rc == 0 || rc != -ETXTBSY) | 1543 | if (rc == 0 || rc != -ETXTBSY) |
@@ -1545,29 +1548,28 @@ cifs_do_rename(unsigned int xid, struct dentry *from_dentry, | |||
1545 | goto do_rename_exit; | 1548 | goto do_rename_exit; |
1546 | 1549 | ||
1547 | /* open the file to be renamed -- we need DELETE perms */ | 1550 | /* open the file to be renamed -- we need DELETE perms */ |
1548 | rc = CIFSSMBOpen(xid, pTcon, fromPath, FILE_OPEN, DELETE, | 1551 | rc = CIFSSMBOpen(xid, tcon, from_path, FILE_OPEN, DELETE, |
1549 | CREATE_NOT_DIR, &srcfid, &oplock, NULL, | 1552 | CREATE_NOT_DIR, &srcfid, &oplock, NULL, |
1550 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & | 1553 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & |
1551 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 1554 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
1552 | |||
1553 | if (rc == 0) { | 1555 | if (rc == 0) { |
1554 | rc = CIFSSMBRenameOpenFile(xid, pTcon, srcfid, | 1556 | rc = CIFSSMBRenameOpenFile(xid, tcon, srcfid, |
1555 | (const char *) to_dentry->d_name.name, | 1557 | (const char *) to_dentry->d_name.name, |
1556 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & | 1558 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & |
1557 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 1559 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
1558 | 1560 | CIFSSMBClose(xid, tcon, srcfid); | |
1559 | CIFSSMBClose(xid, pTcon, srcfid); | ||
1560 | } | 1561 | } |
1561 | do_rename_exit: | 1562 | do_rename_exit: |
1562 | cifs_put_tlink(tlink); | 1563 | cifs_put_tlink(tlink); |
1563 | return rc; | 1564 | return rc; |
1564 | } | 1565 | } |
1565 | 1566 | ||
1566 | int cifs_rename(struct inode *source_dir, struct dentry *source_dentry, | 1567 | int |
1567 | struct inode *target_dir, struct dentry *target_dentry) | 1568 | cifs_rename(struct inode *source_dir, struct dentry *source_dentry, |
1569 | struct inode *target_dir, struct dentry *target_dentry) | ||
1568 | { | 1570 | { |
1569 | char *fromName = NULL; | 1571 | char *from_name = NULL; |
1570 | char *toName = NULL; | 1572 | char *to_name = NULL; |
1571 | struct cifs_sb_info *cifs_sb; | 1573 | struct cifs_sb_info *cifs_sb; |
1572 | struct tcon_link *tlink; | 1574 | struct tcon_link *tlink; |
1573 | struct cifs_tcon *tcon; | 1575 | struct cifs_tcon *tcon; |
@@ -1588,25 +1590,25 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry, | |||
1588 | * we already have the rename sem so we do not need to | 1590 | * we already have the rename sem so we do not need to |
1589 | * grab it again here to protect the path integrity | 1591 | * grab it again here to protect the path integrity |
1590 | */ | 1592 | */ |
1591 | fromName = build_path_from_dentry(source_dentry); | 1593 | from_name = build_path_from_dentry(source_dentry); |
1592 | if (fromName == NULL) { | 1594 | if (from_name == NULL) { |
1593 | rc = -ENOMEM; | 1595 | rc = -ENOMEM; |
1594 | goto cifs_rename_exit; | 1596 | goto cifs_rename_exit; |
1595 | } | 1597 | } |
1596 | 1598 | ||
1597 | toName = build_path_from_dentry(target_dentry); | 1599 | to_name = build_path_from_dentry(target_dentry); |
1598 | if (toName == NULL) { | 1600 | if (to_name == NULL) { |
1599 | rc = -ENOMEM; | 1601 | rc = -ENOMEM; |
1600 | goto cifs_rename_exit; | 1602 | goto cifs_rename_exit; |
1601 | } | 1603 | } |
1602 | 1604 | ||
1603 | rc = cifs_do_rename(xid, source_dentry, fromName, | 1605 | rc = cifs_do_rename(xid, source_dentry, from_name, target_dentry, |
1604 | target_dentry, toName); | 1606 | to_name); |
1605 | 1607 | ||
1606 | if (rc == -EEXIST && tcon->unix_ext) { | 1608 | if (rc == -EEXIST && tcon->unix_ext) { |
1607 | /* | 1609 | /* |
1608 | * Are src and dst hardlinks of same inode? We can | 1610 | * Are src and dst hardlinks of same inode? We can only tell |
1609 | * only tell with unix extensions enabled | 1611 | * with unix extensions enabled. |
1610 | */ | 1612 | */ |
1611 | info_buf_source = | 1613 | info_buf_source = |
1612 | kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO), | 1614 | kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO), |
@@ -1617,19 +1619,19 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry, | |||
1617 | } | 1619 | } |
1618 | 1620 | ||
1619 | info_buf_target = info_buf_source + 1; | 1621 | info_buf_target = info_buf_source + 1; |
1620 | tmprc = CIFSSMBUnixQPathInfo(xid, tcon, fromName, | 1622 | tmprc = CIFSSMBUnixQPathInfo(xid, tcon, from_name, |
1621 | info_buf_source, | 1623 | info_buf_source, |
1622 | cifs_sb->local_nls, | 1624 | cifs_sb->local_nls, |
1623 | cifs_sb->mnt_cifs_flags & | 1625 | cifs_sb->mnt_cifs_flags & |
1624 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 1626 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
1625 | if (tmprc != 0) | 1627 | if (tmprc != 0) |
1626 | goto unlink_target; | 1628 | goto unlink_target; |
1627 | 1629 | ||
1628 | tmprc = CIFSSMBUnixQPathInfo(xid, tcon, toName, | 1630 | tmprc = CIFSSMBUnixQPathInfo(xid, tcon, to_name, |
1629 | info_buf_target, | 1631 | info_buf_target, |
1630 | cifs_sb->local_nls, | 1632 | cifs_sb->local_nls, |
1631 | cifs_sb->mnt_cifs_flags & | 1633 | cifs_sb->mnt_cifs_flags & |
1632 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 1634 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
1633 | 1635 | ||
1634 | if (tmprc == 0 && (info_buf_source->UniqueId == | 1636 | if (tmprc == 0 && (info_buf_source->UniqueId == |
1635 | info_buf_target->UniqueId)) { | 1637 | info_buf_target->UniqueId)) { |
@@ -1637,8 +1639,11 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry, | |||
1637 | rc = 0; | 1639 | rc = 0; |
1638 | goto cifs_rename_exit; | 1640 | goto cifs_rename_exit; |
1639 | } | 1641 | } |
1640 | } /* else ... BB we could add the same check for Windows by | 1642 | } |
1641 | checking the UniqueId via FILE_INTERNAL_INFO */ | 1643 | /* |
1644 | * else ... BB we could add the same check for Windows by | ||
1645 | * checking the UniqueId via FILE_INTERNAL_INFO | ||
1646 | */ | ||
1642 | 1647 | ||
1643 | unlink_target: | 1648 | unlink_target: |
1644 | /* Try unlinking the target dentry if it's not negative */ | 1649 | /* Try unlinking the target dentry if it's not negative */ |
@@ -1646,15 +1651,14 @@ unlink_target: | |||
1646 | tmprc = cifs_unlink(target_dir, target_dentry); | 1651 | tmprc = cifs_unlink(target_dir, target_dentry); |
1647 | if (tmprc) | 1652 | if (tmprc) |
1648 | goto cifs_rename_exit; | 1653 | goto cifs_rename_exit; |
1649 | 1654 | rc = cifs_do_rename(xid, source_dentry, from_name, | |
1650 | rc = cifs_do_rename(xid, source_dentry, fromName, | 1655 | target_dentry, to_name); |
1651 | target_dentry, toName); | ||
1652 | } | 1656 | } |
1653 | 1657 | ||
1654 | cifs_rename_exit: | 1658 | cifs_rename_exit: |
1655 | kfree(info_buf_source); | 1659 | kfree(info_buf_source); |
1656 | kfree(fromName); | 1660 | kfree(from_name); |
1657 | kfree(toName); | 1661 | kfree(to_name); |
1658 | free_xid(xid); | 1662 | free_xid(xid); |
1659 | cifs_put_tlink(tlink); | 1663 | cifs_put_tlink(tlink); |
1660 | return rc; | 1664 | return rc; |