Mirror of git://git.busybox.net/busybox with our patches on top
Source
errcode_t ext2fs_link(ext2_filsys fs, ext2_ino_t dir, const char *name,
/* vi: set sw=4 ts=4: */
/*
* link.c --- create links in a ext2fs directory
*
* Copyright (C) 1993, 1994 Theodore Ts'o.
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Public
* License.
* %End-Header%
*/
struct link_struct {
const char *name;
int namelen;
ext2_ino_t inode;
int flags;
int done;
struct ext2_super_block *sb;
};
static int link_proc(struct ext2_dir_entry *dirent,
int offset,
int blocksize,
char *buf,
void *priv_data)
{
struct link_struct *ls = (struct link_struct *) priv_data;
struct ext2_dir_entry *next;
int rec_len, min_rec_len;
int ret = 0;
rec_len = EXT2_DIR_REC_LEN(ls->namelen);
/*
* See if the following directory entry (if any) is unused;
* if so, absorb it into this one.
*/
next = (struct ext2_dir_entry *) (buf + offset + dirent->rec_len);
if ((offset + dirent->rec_len < blocksize - 8) &&
(next->inode == 0) &&
(offset + dirent->rec_len + next->rec_len <= blocksize)) {
dirent->rec_len += next->rec_len;
ret = DIRENT_CHANGED;
}
/*
* If the directory entry is used, see if we can split the
* directory entry to make room for the new name. If so,
* truncate it and return.
*/
if (dirent->inode) {
min_rec_len = EXT2_DIR_REC_LEN(dirent->name_len & 0xFF);
if (dirent->rec_len < (min_rec_len + rec_len))