/* compose directory item containing "." and ".." entries */ void make_empty_dir_item (char * body, __u32 dirid, __u32 objid, __u32 par_dirid, __u32 par_objid) { struct reiserfs_de_head * deh; memset (body, 0, EMPTY_DIR_SIZE); deh = (struct reiserfs_de_head *)body; /* direntry header of "." */ put_deh_offset( &(deh[0]), DOT_OFFSET ); /* these two are from make_le_item_head, and are are LE */ deh[0].deh_dir_id = dirid; deh[0].deh_objectid = objid; deh[0].deh_state = 0; /* Endian safe if 0 */ put_deh_location( &(deh[0]), EMPTY_DIR_SIZE - ROUND_UP( strlen( "." ) ) ); mark_de_visible(&(deh[0])); /* direntry header of ".." */ put_deh_offset( &(deh[1]), DOT_DOT_OFFSET ); /* key of ".." for the root directory */ /* these two are from the inode, and are are LE */ deh[1].deh_dir_id = par_dirid; deh[1].deh_objectid = par_objid; deh[1].deh_state = 0; /* Endian safe if 0 */ put_deh_location( &(deh[1]), deh_location( &(deh[0])) - ROUND_UP( strlen( ".." ) ) ); mark_de_visible(&(deh[1])); /* copy ".." and "." */ memcpy (body + deh_location( &(deh[0]) ), ".", 1); memcpy (body + deh_location( &(deh[1]) ), "..", 2); }
void make_empty_dir_item(char *body, __le32 dirid, __le32 objid, __le32 par_dirid, __le32 par_objid) { struct reiserfs_de_head *deh; memset(body, 0, EMPTY_DIR_SIZE); deh = (struct reiserfs_de_head *)body; put_deh_offset(&(deh[0]), DOT_OFFSET); deh[0].deh_dir_id = dirid; deh[0].deh_objectid = objid; deh[0].deh_state = 0; put_deh_location(&(deh[0]), EMPTY_DIR_SIZE - ROUND_UP(strlen("."))); mark_de_visible(&(deh[0])); put_deh_offset(&(deh[1]), DOT_DOT_OFFSET); deh[1].deh_dir_id = par_dirid; deh[1].deh_objectid = par_objid; deh[1].deh_state = 0; put_deh_location(&(deh[1]), deh_location(&(deh[0])) - ROUND_UP(strlen(".."))); mark_de_visible(&(deh[1])); memcpy(body + deh_location(&(deh[0])), ".", 1); memcpy(body + deh_location(&(deh[1])), "..", 2); }
/* * compose directory item containing "." and ".." entries (entries are * not aligned to 4 byte boundary) */ void make_empty_dir_item_v1(char *body, __le32 dirid, __le32 objid, __le32 par_dirid, __le32 par_objid) { struct reiserfs_de_head *dot, *dotdot; memset(body, 0, EMPTY_DIR_SIZE_V1); dot = (struct reiserfs_de_head *)body; dotdot = dot + 1; /* direntry header of "." */ put_deh_offset(dot, DOT_OFFSET); /* these two are from make_le_item_head, and are are LE */ dot->deh_dir_id = dirid; dot->deh_objectid = objid; dot->deh_state = 0; /* Endian safe if 0 */ put_deh_location(dot, EMPTY_DIR_SIZE_V1 - strlen(".")); mark_de_visible(dot); /* direntry header of ".." */ put_deh_offset(dotdot, DOT_DOT_OFFSET); /* key of ".." for the root directory */ /* these two are from the inode, and are are LE */ dotdot->deh_dir_id = par_dirid; dotdot->deh_objectid = par_objid; dotdot->deh_state = 0; /* Endian safe if 0 */ put_deh_location(dotdot, deh_location(dot) - strlen("..")); mark_de_visible(dotdot); /* copy ".." and "." */ memcpy(body + deh_location(dot), ".", 1); memcpy(body + deh_location(dotdot), "..", 2); }
static int reiserfs_add_entry(struct reiserfs_transaction_handle *th, struct inode *dir, const char *name, int namelen, struct inode *inode, int visible) { struct cpu_key entry_key; struct reiserfs_de_head *deh; INITIALIZE_PATH(path); struct reiserfs_dir_entry de; DECLARE_BITMAP(bit_string, MAX_GENERATION_NUMBER + 1); int gen_number; char small_buf[32 + DEH_SIZE]; /* 48 bytes now and we avoid kmalloc if we create file with short name */ char *buffer; int buflen, paste_size; int retval; BUG_ON(!th->t_trans_id); /* cannot allow items to be added into a busy deleted directory */ if (!namelen) return -EINVAL; if (namelen > REISERFS_MAX_NAME(dir->i_sb->s_blocksize)) return -ENAMETOOLONG; /* each entry has unique key. compose it */ make_cpu_key(&entry_key, dir, get_third_component(dir->i_sb, name, namelen), TYPE_DIRENTRY, 3); /* get memory for composing the entry */ buflen = DEH_SIZE + ROUND_UP(namelen); if (buflen > sizeof(small_buf)) { buffer = kmalloc(buflen, GFP_NOFS); if (!buffer) return -ENOMEM; } else buffer = small_buf; paste_size = (get_inode_sd_version(dir) == STAT_DATA_V1) ? (DEH_SIZE + namelen) : buflen; /* fill buffer : directory entry head, name[, dir objectid | , stat data | ,stat data, dir objectid ] */ deh = (struct reiserfs_de_head *)buffer; deh->deh_location = 0; /* JDM Endian safe if 0 */ put_deh_offset(deh, cpu_key_k_offset(&entry_key)); deh->deh_state = 0; /* JDM Endian safe if 0 */ /* put key (ino analog) to de */ deh->deh_dir_id = INODE_PKEY(inode)->k_dir_id; /* safe: k_dir_id is le */ deh->deh_objectid = INODE_PKEY(inode)->k_objectid; /* safe: k_objectid is le */ /* copy name */ memcpy((char *)(deh + 1), name, namelen); /* padd by 0s to the 4 byte boundary */ padd_item((char *)(deh + 1), ROUND_UP(namelen), namelen); /* entry is ready to be pasted into tree, set 'visibility' and 'stat data in entry' attributes */ mark_de_without_sd(deh); visible ? mark_de_visible(deh) : mark_de_hidden(deh); /* find the proper place for the new entry */ memset(bit_string, 0, sizeof(bit_string)); de.de_gen_number_bit_string = bit_string; retval = reiserfs_find_entry(dir, name, namelen, &path, &de); if (retval != NAME_NOT_FOUND) { if (buffer != small_buf) kfree(buffer); pathrelse(&path); if (retval == IO_ERROR) { return -EIO; } if (retval != NAME_FOUND) { reiserfs_error(dir->i_sb, "zam-7002", "reiserfs_find_entry() returned " "unexpected value (%d)", retval); } return -EEXIST; } gen_number = find_first_zero_bit(bit_string, MAX_GENERATION_NUMBER + 1); if (gen_number > MAX_GENERATION_NUMBER) { /* there is no free generation number */ reiserfs_warning(dir->i_sb, "reiserfs-7010", "Congratulations! we have got hash function " "screwed up"); if (buffer != small_buf) kfree(buffer); pathrelse(&path); return -EBUSY; } /* adjust offset of directory enrty */ put_deh_offset(deh, SET_GENERATION_NUMBER(deh_offset(deh), gen_number)); set_cpu_key_k_offset(&entry_key, deh_offset(deh)); /* update max-hash-collisions counter in reiserfs_sb_info */ PROC_INFO_MAX(th->t_super, max_hash_collisions, gen_number); if (gen_number != 0) { /* we need to re-search for the insertion point */ if (search_by_entry_key(dir->i_sb, &entry_key, &path, &de) != NAME_NOT_FOUND) { reiserfs_warning(dir->i_sb, "vs-7032", "entry with this key (%K) already " "exists", &entry_key); if (buffer != small_buf) kfree(buffer); pathrelse(&path); return -EBUSY; } } /* perform the insertion of the entry that we have prepared */ retval = reiserfs_paste_into_item(th, &path, &entry_key, dir, buffer, paste_size); if (buffer != small_buf) kfree(buffer); if (retval) { reiserfs_check_path(&path); return retval; } dir->i_size += paste_size; dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; if (!S_ISDIR(inode->i_mode) && visible) // reiserfs_mkdir or reiserfs_rename will do that by itself reiserfs_update_sd(th, dir); reiserfs_check_path(&path); return 0; }