#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
-#include "xfs_dir.h"
+#include "xfs_ag.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
-#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_bmap.h"
#include "xfs_error.h"
#include "xfs_quota.h"
-#include "xfs_refcache.h"
#include "xfs_utils.h"
#include "xfs_trans_space.h"
-#include "xfs_dir_leaf.h"
+#include "xfs_vnodeops.h"
/*
xfs_lock_for_rename(
xfs_inode_t *dp1, /* old (source) directory inode */
xfs_inode_t *dp2, /* new (target) directory inode */
- vname_t *vname1,/* old entry name */
- vname_t *vname2,/* new entry name */
+ bhv_vname_t *vname1,/* old entry name */
+ bhv_vname_t *vname2,/* new entry name */
xfs_inode_t **ipp1, /* inode of old entry */
xfs_inode_t **ipp2, /* inode of new entry, if it
already exists, NULL otherwise. */
xfs_inode_t **i_tab,/* array of inode returned, sorted */
int *num_inodes) /* number of inodes in array */
{
- xfs_inode_t *ip1, *ip2, *temp;
+ xfs_inode_t *ip1 = VNAME_TO_INODE(vname1);
+ xfs_inode_t *ip2, *temp;
xfs_ino_t inum1, inum2;
int error;
int i, j;
* to see if we still have the right inodes, directories, etc.
*/
lock_mode = xfs_ilock_map_shared(dp1);
- error = xfs_get_dir_entry(vname1, &ip1);
- if (error) {
- xfs_iunlock_map_shared(dp1, lock_mode);
- return error;
- }
+ IHOLD(ip1);
+ xfs_itrace_ref(ip1);
inum1 = ip1->i_ino;
- ASSERT(ip1);
- ITRACE(ip1);
/*
* Unlock dp1 and lock dp2 if they are different.
lock_mode = xfs_ilock_map_shared(dp2);
}
- error = xfs_dir_lookup_int(XFS_ITOBHV(dp2), lock_mode,
- vname2, &inum2, &ip2);
+ error = xfs_dir_lookup_int(dp2, lock_mode, vname2, &inum2, &ip2);
if (error == ENOENT) { /* target does not need to exist. */
inum2 = 0;
} else if (error) {
IRELE (ip1);
return error;
} else {
- ITRACE(ip2);
+ xfs_itrace_ref(ip2);
}
/*
*/
int
xfs_rename(
- bhv_desc_t *src_dir_bdp,
- vname_t *src_vname,
- bhv_vnode_t *target_dir_vp,
- vname_t *target_vname,
- cred_t *credp)
+ xfs_inode_t *src_dp,
+ bhv_vname_t *src_vname,
+ xfs_inode_t *target_dp,
+ bhv_vname_t *target_vname)
{
xfs_trans_t *tp;
- xfs_inode_t *src_dp, *target_dp, *src_ip, *target_ip;
- xfs_mount_t *mp;
+ xfs_inode_t *src_ip, *target_ip;
+ xfs_mount_t *mp = src_dp->i_mount;
int new_parent; /* moving to a new dir */
int src_is_directory; /* src_name is a directory */
int error;
int committed;
xfs_inode_t *inodes[4];
int target_ip_dropped = 0; /* dropped target_ip link? */
- bhv_vnode_t *src_dir_vp;
int spaceres;
int target_link_zero = 0;
int num_inodes;
int src_namelen = VNAMELEN(src_vname);
int target_namelen = VNAMELEN(target_vname);
- src_dir_vp = BHV_TO_VNODE(src_dir_bdp);
- vn_trace_entry(src_dir_vp, "xfs_rename", (inst_t *)__return_address);
- vn_trace_entry(target_dir_vp, "xfs_rename", (inst_t *)__return_address);
-
- /*
- * Find the XFS behavior descriptor for the target directory
- * vnode since it was not handed to us.
- */
- target_dp = xfs_vtoi(target_dir_vp);
- if (target_dp == NULL) {
- return XFS_ERROR(EXDEV);
- }
-
- src_dp = XFS_BHVTOI(src_dir_bdp);
- mp = src_dp->i_mount;
+ xfs_itrace_entry(src_dp);
+ xfs_itrace_entry(target_dp);
- if (DM_EVENT_ENABLED(src_dir_vp->v_vfsp, src_dp, DM_EVENT_RENAME) ||
- DM_EVENT_ENABLED(target_dir_vp->v_vfsp,
- target_dp, DM_EVENT_RENAME)) {
+ if (DM_EVENT_ENABLED(src_dp, DM_EVENT_RENAME) ||
+ DM_EVENT_ENABLED(target_dp, DM_EVENT_RENAME)) {
error = XFS_SEND_NAMESP(mp, DM_EVENT_RENAME,
- src_dir_vp, DM_RIGHT_NULL,
- target_dir_vp, DM_RIGHT_NULL,
+ src_dp, DM_RIGHT_NULL,
+ target_dp, DM_RIGHT_NULL,
src_name, target_name,
0, 0, 0);
if (error) {
* them when they unlock the inodes. Also, we need to be careful
* not to add an inode to the transaction more than once.
*/
- VN_HOLD(src_dir_vp);
+ IHOLD(src_dp);
xfs_trans_ijoin(tp, src_dp, XFS_ILOCK_EXCL);
if (new_parent) {
- VN_HOLD(target_dir_vp);
+ IHOLD(target_dp);
xfs_trans_ijoin(tp, target_dp, XFS_ILOCK_EXCL);
}
if ((src_ip != src_dp) && (src_ip != target_dp)) {
* fit before actually inserting it.
*/
if (spaceres == 0 &&
- (error = XFS_DIR_CANENTER(mp, tp, target_dp, target_name,
- target_namelen))) {
+ (error = xfs_dir_canenter(tp, target_dp, target_name,
+ target_namelen)))
goto error_return;
- }
/*
* If target does not exist and the rename crosses
* directories, adjust the target directory link count
* to account for the ".." reference from the new entry.
*/
- error = XFS_DIR_CREATENAME(mp, tp, target_dp, target_name,
+ error = xfs_dir_createname(tp, target_dp, target_name,
target_namelen, src_ip->i_ino,
&first_block, &free_list, spaceres);
- if (error == ENOSPC) {
+ if (error == ENOSPC)
goto error_return;
- }
- if (error) {
+ if (error)
goto abort_return;
- }
xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
if (new_parent && src_is_directory) {
error = xfs_bumplink(tp, target_dp);
- if (error) {
+ if (error)
goto abort_return;
- }
}
} else { /* target_ip != NULL */
-
/*
* If target exists and it's a directory, check that both
* target and source are directories and that target can be
/*
* Make sure target dir is empty.
*/
- if (!(XFS_DIR_ISEMPTY(target_ip->i_mount, target_ip)) ||
+ if (!(xfs_dir_isempty(target_ip)) ||
(target_ip->i_d.di_nlink > 2)) {
error = XFS_ERROR(EEXIST);
goto error_return;
* In case there is already an entry with the same
* name at the destination directory, remove it first.
*/
- error = XFS_DIR_REPLACE(mp, tp, target_dp, target_name,
- target_namelen, src_ip->i_ino, &first_block,
- &free_list, spaceres);
- if (error) {
+ error = xfs_dir_replace(tp, target_dp, target_name,
+ target_namelen, src_ip->i_ino,
+ &first_block, &free_list, spaceres);
+ if (error)
goto abort_return;
- }
xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
/*
* dir no longer points to it.
*/
error = xfs_droplink(tp, target_ip);
- if (error) {
+ if (error)
goto abort_return;
- }
target_ip_dropped = 1;
if (src_is_directory) {
* Drop the link from the old "." entry.
*/
error = xfs_droplink(tp, target_ip);
- if (error) {
+ if (error)
goto abort_return;
- }
}
/* Do this test while we still hold the locks */
* Remove the source.
*/
if (new_parent && src_is_directory) {
-
/*
* Rewrite the ".." entry to point to the new
* directory.
*/
- error = XFS_DIR_REPLACE(mp, tp, src_ip, "..", 2,
- target_dp->i_ino, &first_block,
- &free_list, spaceres);
+ error = xfs_dir_replace(tp, src_ip, "..", 2, target_dp->i_ino,
+ &first_block, &free_list, spaceres);
ASSERT(error != EEXIST);
- if (error) {
+ if (error)
goto abort_return;
- }
xfs_ichgtime(src_ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
} else {
* entry that's moved no longer points to it.
*/
error = xfs_droplink(tp, src_dp);
- if (error) {
+ if (error)
goto abort_return;
- }
}
- error = XFS_DIR_REMOVENAME(mp, tp, src_dp, src_name, src_namelen,
+ error = xfs_dir_removename(tp, src_dp, src_name, src_namelen,
src_ip->i_ino, &first_block, &free_list, spaceres);
- if (error) {
+ if (error)
goto abort_return;
- }
xfs_ichgtime(src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
/*
IHOLD(target_ip);
IHOLD(src_ip);
- error = xfs_bmap_finish(&tp, &free_list, first_block, &committed);
+ error = xfs_bmap_finish(&tp, &free_list, &committed);
if (error) {
xfs_bmap_cancel(&free_list);
xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES |
* trans_commit will unlock src_ip, target_ip & decrement
* the vnode references.
*/
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
- if (target_ip != NULL) {
- xfs_refcache_purge_ip(target_ip);
+ error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
+ if (target_ip != NULL)
IRELE(target_ip);
- }
/*
* Let interposed file systems know about removed links.
*/
- if (target_ip_dropped) {
- bhv_vop_link_removed(XFS_ITOV(target_ip), target_dir_vp,
- target_link_zero);
+ if (target_ip_dropped)
IRELE(target_ip);
- }
IRELE(src_ip);
/* Fall through to std_return with error = 0 or errno from
* xfs_trans_commit */
std_return:
- if (DM_EVENT_ENABLED(src_dir_vp->v_vfsp, src_dp, DM_EVENT_POSTRENAME) ||
- DM_EVENT_ENABLED(target_dir_vp->v_vfsp,
- target_dp, DM_EVENT_POSTRENAME)) {
+ if (DM_EVENT_ENABLED(src_dp, DM_EVENT_POSTRENAME) ||
+ DM_EVENT_ENABLED(target_dp, DM_EVENT_POSTRENAME)) {
(void) XFS_SEND_NAMESP (mp, DM_EVENT_POSTRENAME,
- src_dir_vp, DM_RIGHT_NULL,
- target_dir_vp, DM_RIGHT_NULL,
+ src_dp, DM_RIGHT_NULL,
+ target_dp, DM_RIGHT_NULL,
src_name, target_name,
0, error, 0);
}