⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 namei.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
📖 第 1 页 / 共 3 页
字号:
    /* 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 = (char *)bit_string;    retval = reiserfs_find_entry (dir, name, namelen, &path, &de);    if( retval != NAME_NOT_FOUND ) {	if (buffer != small_buf)	    reiserfs_kfree (buffer, buflen, dir->i_sb);	pathrelse (&path);        if (retval != NAME_FOUND) {	    reiserfs_warning ("zam-7002:" __FUNCTION__ ": \"reiserfs_find_entry\" has returned"                              " unexpected value (%d)\n", 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 ("reiserfs_add_entry: Congratulations! we have got hash function screwed up\n");      if (buffer != small_buf)          reiserfs_kfree (buffer, buflen, dir->i_sb);      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 ("vs-7032: reiserfs_add_entry: "                            "entry with this key (%k) already exists\n", &entry_key);	    if (buffer != small_buf)		reiserfs_kfree (buffer, buflen, dir->i_sb);	    pathrelse (&path);	    return -EBUSY;	}    }      /* perform the insertion of the entry that we have prepared */    retval = reiserfs_paste_into_item (th, &path, &entry_key, buffer, paste_size);    if (buffer != small_buf)	reiserfs_kfree (buffer, buflen, dir->i_sb);    if (retval) {	reiserfs_check_path(&path) ;	return retval;    }    dir->i_size += paste_size;    dir->i_blocks = ((dir->i_size + 511) >> 9);    dir->i_mtime = dir->i_ctime = CURRENT_TIME;    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;}//// a portion of this function, particularly the VFS interface portion,// was derived from minix or ext2's analog and evolved as the// prototype did. You should be able to tell which portion by looking// at the ext2 code and comparing. It's subfunctions contain no code// used as a template unless they are so labeled.//static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode){    int retval;    struct inode * inode;    int windex ;    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 ;    struct reiserfs_transaction_handle th ;    inode = new_inode(dir->i_sb) ;    if (!inode) {	return -ENOMEM ;    }    journal_begin(&th, dir->i_sb, jbegin_count) ;    th.t_caller = "create" ;    windex = push_journal_writer("reiserfs_create") ;    inode = reiserfs_new_inode (&th, dir, mode, 0, 0/*i_size*/, dentry, inode, &retval);    if (!inode) {	pop_journal_writer(windex) ;	journal_end(&th, dir->i_sb, jbegin_count) ;	return retval;    }	    inode->i_op = &reiserfs_file_inode_operations;    inode->i_fop = &reiserfs_file_operations;    inode->i_mapping->a_ops = &reiserfs_address_space_operations ;    retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, 				inode, 1/*visible*/);    if (retval) {	inode->i_nlink--;	reiserfs_update_sd (&th, inode);	pop_journal_writer(windex) ;	// FIXME: should we put iput here and have stat data deleted	// in the same transactioin	journal_end(&th, dir->i_sb, jbegin_count) ;	iput (inode);	return retval;    }    reiserfs_update_inode_transaction(inode) ;    reiserfs_update_inode_transaction(dir) ;    d_instantiate(dentry, inode);    pop_journal_writer(windex) ;    journal_end(&th, dir->i_sb, jbegin_count) ;    return 0;}//// a portion of this function, particularly the VFS interface portion,// was derived from minix or ext2's analog and evolved as the// prototype did. You should be able to tell which portion by looking// at the ext2 code and comparing. It's subfunctions contain no code// used as a template unless they are so labeled.//static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev){    int retval;    struct inode * inode;    int windex ;    struct reiserfs_transaction_handle th ;    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;     inode = new_inode(dir->i_sb) ;    if (!inode) {	return -ENOMEM ;    }    journal_begin(&th, dir->i_sb, jbegin_count) ;    windex = push_journal_writer("reiserfs_mknod") ;    inode = reiserfs_new_inode (&th, dir, mode, 0, 0/*i_size*/, dentry, inode, &retval);    if (!inode) {	pop_journal_writer(windex) ;	journal_end(&th, dir->i_sb, jbegin_count) ;	return retval;    }    init_special_inode(inode, mode, rdev) ;    //FIXME: needed for block and char devices only    reiserfs_update_sd (&th, inode);    reiserfs_update_inode_transaction(inode) ;    reiserfs_update_inode_transaction(dir) ;    retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, 				 inode, 1/*visible*/);    if (retval) {	inode->i_nlink--;	reiserfs_update_sd (&th, inode);	pop_journal_writer(windex) ;	journal_end(&th, dir->i_sb, jbegin_count) ;	iput (inode);	return retval;    }    d_instantiate(dentry, inode);    pop_journal_writer(windex) ;    journal_end(&th, dir->i_sb, jbegin_count) ;    return 0;}//// a portion of this function, particularly the VFS interface portion,// was derived from minix or ext2's analog and evolved as the// prototype did. You should be able to tell which portion by looking// at the ext2 code and comparing. It's subfunctions contain no code// used as a template unless they are so labeled.//static int reiserfs_mkdir (struct inode * dir, struct dentry *dentry, int mode){    int retval;    struct inode * inode;    int windex ;    struct reiserfs_transaction_handle th ;    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;     inode = new_inode(dir->i_sb) ;    if (!inode) {	return -ENOMEM ;    }    journal_begin(&th, dir->i_sb, jbegin_count) ;    windex = push_journal_writer("reiserfs_mkdir") ;    /* inc the link count now, so another writer doesn't overflow it while    ** we sleep later on.    */    INC_DIR_INODE_NLINK(dir)    mode = S_IFDIR | mode;    inode = reiserfs_new_inode (&th, dir, mode, 0/*symlink*/,				old_format_only (dir->i_sb) ? EMPTY_DIR_SIZE_V1 : EMPTY_DIR_SIZE,				dentry, inode, &retval);    if (!inode) {	pop_journal_writer(windex) ;	dir->i_nlink-- ;	journal_end(&th, dir->i_sb, jbegin_count) ;	return retval;    }    reiserfs_update_inode_transaction(inode) ;    reiserfs_update_inode_transaction(dir) ;    inode->i_op = &reiserfs_dir_inode_operations;    inode->i_fop = &reiserfs_dir_operations;    // note, _this_ add_entry will not update dir's stat data    retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, 				inode, 1/*visible*/);    if (retval) {	inode->i_nlink = 0;	DEC_DIR_INODE_NLINK(dir);	reiserfs_update_sd (&th, inode);	pop_journal_writer(windex) ;	journal_end(&th, dir->i_sb, jbegin_count) ;	iput (inode);	return retval;    }    // the above add_entry did not update dir's stat data    reiserfs_update_sd (&th, dir);    d_instantiate(dentry, inode);    pop_journal_writer(windex) ;    journal_end(&th, dir->i_sb, jbegin_count) ;    return 0;}static inline int reiserfs_empty_dir(struct inode *inode) {    /* we can cheat because an old format dir cannot have    ** EMPTY_DIR_SIZE, and a new format dir cannot have    ** EMPTY_DIR_SIZE_V1.  So, if the inode is either size,     ** regardless of disk format version, the directory is empty.    */    if (inode->i_size != EMPTY_DIR_SIZE &&        inode->i_size != EMPTY_DIR_SIZE_V1) {        return 0 ;    }    return 1 ;}//// a portion of this function, particularly the VFS interface portion,// was derived from minix or ext2's analog and evolved as the// prototype did. You should be able to tell which portion by looking// at the ext2 code and comparing. It's subfunctions contain no code// used as a template unless they are so labeled.//static int reiserfs_rmdir (struct inode * dir, struct dentry *dentry){    int retval;    struct inode * inode;    int windex ;    struct reiserfs_transaction_handle th ;    int jbegin_count;     INITIALIZE_PATH (path);    struct reiserfs_dir_entry de;    /* we will be doing 2 balancings and update 2 stat data */    jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2;    journal_begin(&th, dir->i_sb, jbegin_count) ;    windex = push_journal_writer("reiserfs_rmdir") ;    de.de_gen_number_bit_string = 0;    if (reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path, &de) == NAME_NOT_FOUND) {	retval = -ENOENT;	goto end_rmdir;    }    inode = dentry->d_inode;    reiserfs_update_inode_transaction(inode) ;    reiserfs_update_inode_transaction(dir) ;    if (de.de_objectid != inode->i_ino) {	// FIXME: compare key of an object and a key found in the	// entry	retval = -EIO;	goto end_rmdir;    }    if (!reiserfs_empty_dir(inode)) {	retval = -ENOTEMPTY;	goto end_rmdir;    }    /* cut entry from dir directory */    retval = reiserfs_cut_from_item (&th, &path, &(de.de_entry_key), dir,                                      NULL, /* page */ 				     0/*new file size - not used here*/);    if (retval < 0)	goto end_rmdir;    if ( inode->i_nlink != 2 && inode->i_nlink != 1 )	printk ("reiserfs_rmdir: empty directory has nlink != 2 (%d)\n", inode->i_nlink);    inode->i_nlink = 0;    inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;    reiserfs_update_sd (&th, inode);    DEC_DIR_INODE_NLINK(dir)    dir->i_size -= (DEH_SIZE + de.de_entrylen);    dir->i_blocks = ((dir->i_size + 511) >> 9);    reiserfs_update_sd (&th, dir);    /* prevent empty directory from getting lost */    add_save_link (&th, inode, 0/* not truncate */);    pop_journal_writer(windex) ;    journal_end(&th, dir->i_sb, jbegin_count) ;    reiserfs_check_path(&path) ;    return 0;	 end_rmdir:    /* we must release path, because we did not call       reiserfs_cut_from_item, or reiserfs_cut_from_item does not       release path if operation was not complete */    pathrelse (&path);    pop_journal_writer(windex) ;    journal_end(&th, dir->i_sb, jbegin_count) ;    return retval;	}//// a portion of this function, particularly the VFS interface portion,// was derived from minix or ext2's analog and evolved as the// prototype did. You should be able to tell which portion by looking// at the ext2 code and comparing. It's subfunctions contain no code// used as a template unless they are so labeled.//static int reiserfs_unlink (struct inode * dir, struct dentry *dentry){    int retval;    struct inode * inode;    struct reiserfs_dir_entry de;    INITIALIZE_PATH (path);    int windex ;    struct reiserfs_transaction_handle th ;    int jbegin_count;    inode = dentry->d_inode;    /* in this transaction we can be doing at max two balancings and update       two stat datas */    jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2;    journal_begin(&th, dir->i_sb, jbegin_count) ;    windex = push_journal_writer("reiserfs_unlink") ;	    de.de_gen_number_bit_string = 0;    if (reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path, &de) == NAME_NOT_FOUND) {	retval = -ENOENT;	goto end_unlink;    }    reiserfs_update_inode_transaction(inode) ;    reiserfs_update_inode_transaction(dir) ;    if (de.de_objectid != inode->i_ino) {	// FIXME: compare key of an object and a key found in the	// entry	retval = -EIO;	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;    }    retval = reiserfs_cut_from_item (&th, &path, &(de.de_entry_key), dir, NULL, 0);    if (retval < 0)	goto end_unlink;    inode->i_nlink--;    inode->i_ctime = CURRENT_TIME;    reiserfs_update_sd (&th, inode);    dir->i_size -= (de.de_entrylen + DEH_SIZE);    dir->i_blocks = ((dir->i_size + 511) >> 9);    dir->i_ctime = dir->i_mtime = CURRENT_TIME;    reiserfs_update_sd (&th, dir);    if (!inode->i_nlink)       /* prevent file from getting lost */       add_save_link (&th, inode, 0/* not truncate */);    pop_journal_writer(windex) ;    journal_end(&th, dir->i_sb, jbegin_count) ;    reiserfs_check_path(&path) ;    return 0; end_unlink:    pathrelse (&path);    pop_journal_writer(windex) ;    journal_end(&th, dir->i_sb, jbegin_count) ;    reiserfs_check_path(&path) ;    return retval;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -