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

📄 namei.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
📖 第 1 页 / 共 3 页
字号:
//// 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_symlink (struct inode * dir, struct dentry * dentry, const char * symname){    int retval;    struct inode * inode;    char * name;    int item_len;    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 ;    }    item_len = ROUND_UP (strlen (symname));    if (item_len > MAX_DIRECT_ITEM_LEN (dir->i_sb->s_blocksize)) {	iput(inode) ;	return -ENAMETOOLONG;    }      name = kmalloc (item_len, GFP_NOFS);    if (!name) {	iput(inode) ;	return -ENOMEM;    }    memcpy (name, symname, strlen (symname));    padd_item (name, item_len, strlen (symname));    journal_begin(&th, dir->i_sb, jbegin_count) ;    windex = push_journal_writer("reiserfs_symlink") ;    inode = reiserfs_new_inode (&th, dir, S_IFLNK | S_IRWXUGO, name, strlen (symname), dentry,				inode, &retval);    kfree (name);    if (inode == 0) { /* reiserfs_new_inode iputs for us */	pop_journal_writer(windex) ;	journal_end(&th, dir->i_sb, jbegin_count) ;	return retval;    }    reiserfs_update_inode_transaction(inode) ;    reiserfs_update_inode_transaction(dir) ;    inode->i_op = &page_symlink_inode_operations;    inode->i_mapping->a_ops = &reiserfs_address_space_operations;    // must be sure this inode is written with this transaction    //    //reiserfs_update_sd (&th, inode, READ_BLOCKS);    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_link (struct dentry * old_dentry, struct inode * dir, struct dentry * dentry){    int retval;    struct inode *inode = old_dentry->d_inode;    int windex ;    struct reiserfs_transaction_handle th ;    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;     if (S_ISDIR(inode->i_mode))	return -EPERM;      if (inode->i_nlink >= REISERFS_LINK_MAX) {	//FIXME: sd_nlink is 32 bit for new files	return -EMLINK;    }    journal_begin(&th, dir->i_sb, jbegin_count) ;    windex = push_journal_writer("reiserfs_link") ;    /* create new entry */    retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len,				 inode, 1/*visible*/);    reiserfs_update_inode_transaction(inode) ;    reiserfs_update_inode_transaction(dir) ;    if (retval) {	pop_journal_writer(windex) ;	journal_end(&th, dir->i_sb, jbegin_count) ;	return retval;    }    inode->i_nlink++;    inode->i_ctime = CURRENT_TIME;    reiserfs_update_sd (&th, inode);    atomic_inc(&inode->i_count) ;    d_instantiate(dentry, inode);    pop_journal_writer(windex) ;    journal_end(&th, dir->i_sb, jbegin_count) ;    return 0;}// de contains information pointing to an entry which static int de_still_valid (const char * name, int len, struct reiserfs_dir_entry * de){    struct reiserfs_dir_entry tmp = *de;        // recalculate pointer to name and name length    set_de_name_and_namelen (&tmp);    // FIXME: could check more    if (tmp.de_namelen != len || memcmp (name, de->de_name, len))	return 0;    return 1;}static int entry_points_to_object (const char * name, int len, struct reiserfs_dir_entry * de, struct inode * inode){    if (!de_still_valid (name, len, de))	return 0;    if (inode) {	if (!de_visible (de->de_deh + de->de_entry_num))	    reiserfs_panic (0, "vs-7042: entry_points_to_object: entry must be visible");	return (de->de_objectid == inode->i_ino) ? 1 : 0;    }    /* this must be added hidden entry */    if (de_visible (de->de_deh + de->de_entry_num))	reiserfs_panic (0, "vs-7043: entry_points_to_object: entry must be visible");    return 1;}/* sets key of objectid the entry has to point to */static void set_ino_in_dir_entry (struct reiserfs_dir_entry * de, struct key * key){    /* JDM These operations are endian safe - both are le */    de->de_deh[de->de_entry_num].deh_dir_id = key->k_dir_id;    de->de_deh[de->de_entry_num].deh_objectid = key->k_objectid;}//// 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.///*  * process, that is going to call fix_nodes/do_balance must hold only * one path. If it holds 2 or more, it can get into endless waiting in * get_empty_nodes or its clones  */static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry,			    struct inode * new_dir, struct dentry *new_dentry){    int retval;    INITIALIZE_PATH (old_entry_path);    INITIALIZE_PATH (new_entry_path);    INITIALIZE_PATH (dot_dot_entry_path);    struct item_head new_entry_ih, old_entry_ih, dot_dot_ih ;    struct reiserfs_dir_entry old_de, new_de, dot_dot_de;    struct inode * old_inode, * new_inode;    int windex ;    struct reiserfs_transaction_handle th ;    int jbegin_count ;     /* two balancings: old name removal, new name insertion or "save" link,       stat data updates: old directory and new directory and maybe block       containing ".." of renamed directory */    jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 3;    old_inode = old_dentry->d_inode;    new_inode = new_dentry->d_inode;    // make sure, that oldname still exists and points to an object we    // are going to rename    old_de.de_gen_number_bit_string = 0;    retval = reiserfs_find_entry (old_dir, old_dentry->d_name.name, old_dentry->d_name.len,				  &old_entry_path, &old_de);    pathrelse (&old_entry_path);    if (retval != NAME_FOUND || old_de.de_objectid != old_inode->i_ino) {	// FIXME: IO error is possible here	return -ENOENT;    }    if (S_ISDIR(old_inode->i_mode)) {	// make sure, that directory being renamed has correct ".." 	// and that its new parent directory has not too many links	// already	if (new_inode) {	    if (!reiserfs_empty_dir(new_inode)) {		return -ENOTEMPTY;	    }	}		/* directory is renamed, its parent directory will be changed, 	** so find ".." entry 	*/	dot_dot_de.de_gen_number_bit_string = 0;	retval = reiserfs_find_entry (old_inode, "..", 2, &dot_dot_entry_path, &dot_dot_de);	pathrelse (&dot_dot_entry_path);	if (retval != NAME_FOUND)	    return -EIO;	/* inode number of .. must equal old_dir->i_ino */	if (dot_dot_de.de_objectid != old_dir->i_ino)	    return -EIO;    }    journal_begin(&th, old_dir->i_sb, jbegin_count) ;    windex = push_journal_writer("reiserfs_rename") ;    /* add new entry (or find the existing one) */    retval = reiserfs_add_entry (&th, new_dir, new_dentry->d_name.name, new_dentry->d_name.len, 				 old_inode, 0);    if (retval == -EEXIST) {	// FIXME: is it possible, that new_inode == 0 here? If yes, it	// is not clear how does ext2 handle that	if (!new_inode) {	    reiserfs_panic (old_dir->i_sb,			    "vs-7050: new entry is found, new inode == 0\n");	}    } else if (retval) {	pop_journal_writer(windex) ;	journal_end(&th, old_dir->i_sb, jbegin_count) ;	return retval;    }    reiserfs_update_inode_transaction(old_dir) ;    reiserfs_update_inode_transaction(new_dir) ;    /* this makes it so an fsync on an open fd for the old name will    ** commit the rename operation    */    reiserfs_update_inode_transaction(old_inode) ;    if (new_inode) 	reiserfs_update_inode_transaction(new_inode) ;    while (1) {	// look for old name using corresponding entry key (found by reiserfs_find_entry)	if (search_by_entry_key (new_dir->i_sb, &old_de.de_entry_key, &old_entry_path, &old_de) != NAME_FOUND)	    BUG ();	copy_item_head(&old_entry_ih, get_ih(&old_entry_path)) ;	reiserfs_prepare_for_journal(old_inode->i_sb, old_de.de_bh, 1) ;	// look for new name by reiserfs_find_entry	new_de.de_gen_number_bit_string = 0;	retval = reiserfs_find_entry (new_dir, new_dentry->d_name.name, new_dentry->d_name.len, 				      &new_entry_path, &new_de);	if (retval != NAME_FOUND_INVISIBLE && retval != NAME_FOUND)	    BUG ();	copy_item_head(&new_entry_ih, get_ih(&new_entry_path)) ;	reiserfs_prepare_for_journal(old_inode->i_sb, new_de.de_bh, 1) ;	if (S_ISDIR(old_inode->i_mode)) {	    if (search_by_entry_key (new_dir->i_sb, &dot_dot_de.de_entry_key, &dot_dot_entry_path, &dot_dot_de) != NAME_FOUND)		BUG ();	    copy_item_head(&dot_dot_ih, get_ih(&dot_dot_entry_path)) ;	    // node containing ".." gets into transaction	    reiserfs_prepare_for_journal(old_inode->i_sb, dot_dot_de.de_bh, 1) ;	}				/* we should check seals here, not do                                   this stuff, yes? Then, having                                   gathered everything into RAM we                                   should lock the buffers, yes?  -Hans */				/* probably.  our rename needs to hold more 				** than one path at once.  The seals would 				** have to be written to deal with multi-path 				** issues -chris				*/	/* sanity checking before doing the rename - avoid races many	** of the above checks could have scheduled.  We have to be	** sure our items haven't been shifted by another process.	*/	if (item_moved(&new_entry_ih, &new_entry_path) ||	    !entry_points_to_object(new_dentry->d_name.name, 	                            new_dentry->d_name.len,				    &new_de, new_inode) ||	    item_moved(&old_entry_ih, &old_entry_path) || 	    !entry_points_to_object (old_dentry->d_name.name, 	                             old_dentry->d_name.len,				     &old_de, old_inode)) {	    reiserfs_restore_prepared_buffer (old_inode->i_sb, new_de.de_bh);	    reiserfs_restore_prepared_buffer (old_inode->i_sb, old_de.de_bh);	    if (S_ISDIR(old_inode->i_mode))		reiserfs_restore_prepared_buffer (old_inode->i_sb, dot_dot_de.de_bh);	    continue;	}	if (S_ISDIR(old_inode->i_mode)) {	    if ( item_moved(&dot_dot_ih, &dot_dot_entry_path) ||		 !entry_points_to_object ( "..", 2, &dot_dot_de, old_dir) ) {		reiserfs_restore_prepared_buffer (old_inode->i_sb, old_de.de_bh);		reiserfs_restore_prepared_buffer (old_inode->i_sb, new_de.de_bh);		reiserfs_restore_prepared_buffer (old_inode->i_sb, dot_dot_de.de_bh);		continue;	    }	}	RFALSE( S_ISDIR(old_inode->i_mode) && 		!reiserfs_buffer_prepared(dot_dot_de.de_bh), "" );	break;    }    /* ok, all the changes can be done in one fell swoop when we       have claimed all the buffers needed.*/        mark_de_visible (new_de.de_deh + new_de.de_entry_num);    set_ino_in_dir_entry (&new_de, INODE_PKEY (old_inode));    journal_mark_dirty (&th, old_dir->i_sb, new_de.de_bh);    mark_de_hidden (old_de.de_deh + old_de.de_entry_num);    journal_mark_dirty (&th, old_dir->i_sb, old_de.de_bh);    old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;    new_dir->i_ctime = new_dir->i_mtime = CURRENT_TIME;    if (new_inode) {	// adjust link number of the victim	if (S_ISDIR(new_inode->i_mode)) {	    new_inode->i_nlink  = 0;	} else {	    new_inode->i_nlink--;	}	new_inode->i_ctime = CURRENT_TIME;    }    if (S_ISDIR(old_inode->i_mode)) {	// adjust ".." of renamed directory 	set_ino_in_dir_entry (&dot_dot_de, INODE_PKEY (new_dir));	journal_mark_dirty (&th, new_dir->i_sb, dot_dot_de.de_bh);	        if (!new_inode)	    /* there (in new_dir) was no directory, so it got new link	       (".."  of renamed directory) */	    INC_DIR_INODE_NLINK(new_dir);			/* old directory lost one link - ".. " of renamed directory */	DEC_DIR_INODE_NLINK(old_dir);    }    // looks like in 2.3.99pre3 brelse is atomic. so we can use pathrelse    pathrelse (&new_entry_path);    pathrelse (&dot_dot_entry_path);    // FIXME: this reiserfs_cut_from_item's return value may screw up    // anybody, but it will panic if will not be able to find the    // entry. This needs one more clean up    if (reiserfs_cut_from_item (&th, &old_entry_path, &(old_de.de_entry_key), old_dir, NULL, 0) < 0)	reiserfs_warning ("vs-7060: reiserfs_rename: couldn't not cut old name. Fsck later?\n");    old_dir->i_size -= DEH_SIZE + old_de.de_entrylen;    old_dir->i_blocks = ((old_dir->i_size + 511) >> 9);    reiserfs_update_sd (&th, old_dir);    reiserfs_update_sd (&th, new_dir);    if (new_inode) {	if (new_inode->i_nlink == 0)	    add_save_link (&th, new_inode, 0/* not truncate */);	reiserfs_update_sd (&th, new_inode);    }    pop_journal_writer(windex) ;    journal_end(&th, old_dir->i_sb, jbegin_count) ;    return 0;}/* * directories can handle most operations... */struct inode_operations reiserfs_dir_inode_operations = {  //&reiserfs_dir_operations,	/* default_file_ops */    create:	reiserfs_create,    lookup:	reiserfs_lookup,    link:	reiserfs_link,    unlink:	reiserfs_unlink,    symlink:	reiserfs_symlink,    mkdir:	reiserfs_mkdir,    rmdir:	reiserfs_rmdir,    mknod:	reiserfs_mknod,    rename:	reiserfs_rename,};

⌨️ 快捷键说明

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