/* * k1 is pointer to on-disk structure which is stored in little-endian * form. k2 is pointer to cpu variable. Compare keys using all 4 key * fields. * Returns: -1 if key1 < key2, 0 if key1 = key2 or 1 if key1 > key2 */ /*inline*/ int comp_keys(const struct key *le_key, const struct cpu_key *cpu_key) { int retval; retval = comp_short_keys(le_key, cpu_key); if (retval) return retval; if (le_key_k_offset(le_key_version(le_key), le_key) < cpu_key_k_offset(cpu_key)) return (-1); if (le_key_k_offset(le_key_version(le_key), le_key) > cpu_key_k_offset(cpu_key)) return (1); if (cpu_key->key_length == 3) return (0); /* This part is needed only when tail conversion is in progress */ if (le_key_k_type(le_key_version(le_key), le_key) < cpu_key_k_type(cpu_key)) return (-1); if (le_key_k_type(le_key_version(le_key), le_key) > cpu_key_k_type(cpu_key)) return (1); return (0); }
/* k1 is pointer to on-disk structure which is stored in little-endian form. k2 is pointer to cpu variable. Compare keys using all 4 key fields. Returns: -1 if key1 < key2 0 if key1 = key2 1 if key1 > key2 */ static inline int comp_keys(const struct reiserfs_key *le_key, const struct cpu_key *cpu_key) { int retval; retval = comp_short_keys(le_key, cpu_key); if (retval) return retval; if (le_key_k_offset(le_key_version(le_key), le_key) < cpu_key_k_offset(cpu_key)) return -1; if (le_key_k_offset(le_key_version(le_key), le_key) > cpu_key_k_offset(cpu_key)) return 1; if (cpu_key->key_length == 3) return 0; /* this part is needed only when tail conversion is in progress */ if (le_key_k_type(le_key_version(le_key), le_key) < cpu_key_k_type(cpu_key)) return -1; if (le_key_k_type(le_key_version(le_key), le_key) > cpu_key_k_type(cpu_key)) return 1; return 0; }
/* Compare keys using all 4 key fields. Returns: -1 if key1 < key2 0 if key1 = key2 1 if key1 > key2 */ int comp_keys (void * p1, void * p2) { int retval; struct key * k1, * k2; k1 = p1; k2 = p2; retval = comp_short_keys (k1, k2); if (retval) return retval; if (get_offset (k1) < get_offset (k2)) return -1; if (get_offset (k1) > get_offset (k2)) return 1; /* this part is needed only when tail conversion is in progress */ if (get_type (k1) < get_type (k2)) return -1; if (get_type (k1) > get_type (k2)) return 1; return 0; }
/* The function is NOT SCHEDULE-SAFE! */ int search_for_position_by_key(struct reiserfs_sb_info *p_s_sbi, const struct cpu_key *p_cpu_key, /* Key to search (cpu variable) */ struct path *p_s_search_path) /* Filled up by this function. */ { int retval, n_blk_size; off_t item_offset, offset; struct item_head *p_le_ih; /* Pointer to on-disk structure */ struct reiserfs_dir_entry de; /* If searching for directory entry. */ if (is_direntry_cpu_key(p_cpu_key)) return (search_by_entry_key(p_s_sbi, p_cpu_key, p_s_search_path, &de)); /* If not searching for directory entry. */ /* If item is found. */ retval = search_item(p_s_sbi, p_cpu_key, p_s_search_path); if (retval == IO_ERROR) return (retval); if (retval == ITEM_FOUND) { if (ih_item_len(B_N_PITEM_HEAD( PATH_PLAST_BUFFER(p_s_search_path), PATH_LAST_POSITION(p_s_search_path))) == 0) { reiserfs_log(LOG_WARNING, "item length equals zero\n"); } pos_in_item(p_s_search_path) = 0; return (POSITION_FOUND); } if (PATH_LAST_POSITION(p_s_search_path) == 0) { reiserfs_log(LOG_WARNING, "position equals zero\n"); } /* Item is not found. Set path to the previous item. */ p_le_ih = B_N_PITEM_HEAD(PATH_PLAST_BUFFER(p_s_search_path), --PATH_LAST_POSITION(p_s_search_path)); n_blk_size = p_s_sbi->s_blocksize; if (comp_short_keys(&(p_le_ih->ih_key), p_cpu_key)) { return (FILE_NOT_FOUND); } item_offset = le_ih_k_offset(p_le_ih); offset = cpu_key_k_offset(p_cpu_key); /* Needed byte is contained in the item pointed to by the path.*/ if (item_offset <= offset && item_offset + op_bytes_number(p_le_ih, n_blk_size) > offset) { pos_in_item(p_s_search_path) = offset - item_offset; if (is_indirect_le_ih(p_le_ih)) { pos_in_item(p_s_search_path) /= n_blk_size; } return (POSITION_FOUND); } /* Needed byte is not contained in the item pointed to by the * path. Set pos_in_item out of the item. */ if (is_indirect_le_ih(p_le_ih)) pos_in_item(p_s_search_path) = ih_item_len(p_le_ih) / UNFM_P_SIZE; else pos_in_item(p_s_search_path) = ih_item_len(p_le_ih); return (POSITION_NOT_FOUND); }
int reiserfs_unlink (struct inode * dir, struct dentry *dentry) { int retval; struct inode * inode; struct reiserfs_dir_entry de; struct path path; int windex ; int call_journal_end = 1 ; struct reiserfs_transaction_handle th ; int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; init_path (&path); retval = -ENOENT; journal_begin(&th, dir->i_sb, jbegin_count) ; windex = push_journal_writer("reiserfs_unlink") ; /* free preserve list if we should */ /* maybe_free_preserve_list (dir->i_sb);*/ de.de_gen_number_bit_string = 0; if (reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path, &de) == POSITION_NOT_FOUND) { goto end_unlink; } inode = dentry->d_inode; reiserfs_update_inode_transaction(inode) ; reiserfs_update_inode_transaction(dir) ; retval = -EPERM; if (S_ISDIR (inode->i_mode)) { goto end_unlink; } if ((dir->i_mode & S_ISVTX) && !fsuser() && current->fsuid != inode->i_uid && current->fsuid != dir->i_uid) { goto end_unlink; } retval = -ENOENT; if (comp_short_keys ((struct key *)&(de.de_dir_id), INODE_PKEY (inode))) { goto end_unlink; } if (!inode->i_nlink) { printk("reiserfs_unlink: deleting nonexistent file (%s:%lu), %d\n", kdevname(inode->i_dev), inode->i_ino, inode->i_nlink); inode->i_nlink = 1; } if (reiserfs_cut_from_item (&th, dir, dir->i_sb, &path, &(de.de_entry_num), &(de.de_entry_key), 0, NOTHING_SPECIAL) == 0) { retval = -ENOENT; goto end_unlink; } inode->i_nlink--; inode->i_ctime = CURRENT_TIME; if_in_ram_update_sd (&th, inode); dir->i_size -= (de.de_entrylen + DEH_SIZE); dir->i_ctime = dir->i_mtime = CURRENT_TIME; if_in_ram_update_sd (&th, dir) ; pop_journal_writer(windex) ; journal_end(&th, dir->i_sb, jbegin_count) ; call_journal_end = 0 ; d_delete(dentry); retval = 0; end_unlink: pathrelse (&path); pop_journal_writer(windex) ; if (call_journal_end) journal_end(&th, dir->i_sb, jbegin_count) ; return retval; }