/* * Remove an entry from a directory. */ int xfs_dir_removename( xfs_trans_t *tp, xfs_inode_t *dp, struct xfs_name *name, xfs_ino_t ino, xfs_fsblock_t *first, /* bmap's firstblock */ xfs_bmap_free_t *flist, /* bmap's freeblock list */ xfs_extlen_t total) /* bmap's total block count */ { struct xfs_da_args *args; int rval; int v; /* type-checking value */ ASSERT(S_ISDIR(dp->i_d.di_mode)); XFS_STATS_INC(xs_dir_remove); args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS); if (!args) return -ENOMEM; args->geo = dp->i_mount->m_dir_geo; args->name = name->name; args->namelen = name->len; args->filetype = name->type; args->hashval = dp->i_mount->m_dirnameops->hashname(name); args->inumber = ino; args->dp = dp; args->firstblock = first; args->flist = flist; args->total = total; args->whichfork = XFS_DATA_FORK; args->trans = tp; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { rval = xfs_dir2_sf_removename(args); goto out_free; } rval = xfs_dir2_isblock(args, &v); if (rval) goto out_free; if (v) { rval = xfs_dir2_block_removename(args); goto out_free; } rval = xfs_dir2_isleaf(args, &v); if (rval) goto out_free; if (v) rval = xfs_dir2_leaf_removename(args); else rval = xfs_dir2_node_removename(args); out_free: kmem_free(args); return rval; }
/* * Like xfs_dir_removename, but only for removing entries with * (name, hashvalue) pairs that may not be consistent (hashvalue * may not be correctly set for the name). * * This was originally in the kernel, but only used in xfs_repair. */ int xfs_dir2_bogus_removename( xfs_trans_t *tp, /* transaction pointer */ xfs_inode_t *dp, /* incore directory inode */ char *name, /* name of entry to remove */ xfs_fsblock_t *first, /* bmap's firstblock */ xfs_bmap_free_t *flist, /* bmap's freeblock list */ xfs_extlen_t total, /* bmap's total block count */ xfs_dahash_t hash, /* name's real hash value */ int namelen) /* entry's name length */ { xfs_da_args_t args; /* operation arguments */ int rval; /* return value */ int v; /* type-checking value */ ASSERT((dp->i_d.di_mode & IFMT) == IFDIR); if (namelen >= MAXNAMELEN) return EINVAL; /* * Fill in the arg structure for this request. */ args.name = name; args.namelen = namelen; args.hashval = hash; args.inumber = 0; args.dp = dp; args.firstblock = first; args.flist = flist; args.total = total; args.whichfork = XFS_DATA_FORK; args.trans = tp; args.justcheck = args.addname = 0; args.oknoent = 1; /* * Decide on what work routines to call based on the inode size. */ if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) rval = xfs_dir2_sf_removename(&args); else if (rval = xfs_dir2_isblock(tp, dp, &v)) return rval; else if (v) rval = xfs_dir2_block_removename(&args); else if (rval = xfs_dir2_isleaf(tp, dp, &v)) return rval; else if (v) rval = xfs_dir2_leaf_removename(&args); else rval = xfs_dir2_node_removename(&args); return rval; }
/* * Remove an entry from a directory. */ int xfs_dir_removename( xfs_trans_t *tp, xfs_inode_t *dp, struct xfs_name *name, xfs_ino_t ino, xfs_fsblock_t *first, /* bmap's firstblock */ xfs_bmap_free_t *flist, /* bmap's freeblock list */ xfs_extlen_t total) /* bmap's total block count */ { xfs_da_args_t args; int rval; int v; /* type-checking value */ ASSERT(S_ISDIR(dp->i_d.di_mode)); XFS_STATS_INC(xs_dir_remove); memset(&args, 0, sizeof(xfs_da_args_t)); args.name = name->name; args.namelen = name->len; args.filetype = name->type; args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.inumber = ino; args.dp = dp; args.firstblock = first; args.flist = flist; args.total = total; args.whichfork = XFS_DATA_FORK; args.trans = tp; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) rval = xfs_dir2_sf_removename(&args); else if ((rval = xfs_dir2_isblock(tp, dp, &v))) return rval; else if (v) rval = xfs_dir2_block_removename(&args); else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) return rval; else if (v) rval = xfs_dir2_leaf_removename(&args); else rval = xfs_dir2_node_removename(&args); return rval; }
/* * Remove an entry from a directory. */ int xfs_dir_removename( xfs_trans_t *tp, xfs_inode_t *dp, char *name, int namelen, xfs_ino_t ino, xfs_fsblock_t *first, /* bmap's firstblock */ xfs_bmap_free_t *flist, /* bmap's freeblock list */ xfs_extlen_t total) /* bmap's total block count */ { xfs_da_args_t args; int rval; int v; /* type-checking value */ ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); XFS_STATS_INC(xs_dir_remove); args.name = name; args.namelen = namelen; args.hashval = xfs_da_hashname(name, namelen); args.inumber = ino; args.dp = dp; args.firstblock = first; args.flist = flist; args.total = total; args.whichfork = XFS_DATA_FORK; args.trans = tp; args.justcheck = args.addname = args.oknoent = 0; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) rval = xfs_dir2_sf_removename(&args); else if ((rval = xfs_dir2_isblock(tp, dp, &v))) return rval; else if (v) rval = xfs_dir2_block_removename(&args); else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) return rval; else if (v) rval = xfs_dir2_leaf_removename(&args); else rval = xfs_dir2_node_removename(&args); return rval; }