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

📄 namei.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 3 页
字号:
    pathrelse (&path);    journal_end(&th, dir->i_sb, jbegin_count) ;    reiserfs_check_path(&path) ;    reiserfs_write_unlock(dir->i_sb);    return retval;}static int reiserfs_symlink (struct inode * parent_dir,                             struct dentry * dentry, const char * symname){    int retval;    struct inode * inode;    char * name;    int item_len;    struct reiserfs_transaction_handle th ;    int mode = S_IFLNK | S_IRWXUGO;    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;     if (!(inode = new_inode(parent_dir->i_sb))) {	return -ENOMEM ;    }    retval = new_inode_init(inode, parent_dir, mode);    if (retval) {        return retval;    }    reiserfs_write_lock(parent_dir->i_sb);    item_len = ROUND_UP (strlen (symname));    if (item_len > MAX_DIRECT_ITEM_LEN (parent_dir->i_sb->s_blocksize)) {	retval =  -ENAMETOOLONG;	drop_new_inode(inode);	goto out_failed;    }      name = reiserfs_kmalloc (item_len, GFP_NOFS, parent_dir->i_sb);    if (!name) {	drop_new_inode(inode);	retval =  -ENOMEM;	goto out_failed;    }    memcpy (name, symname, strlen (symname));    padd_item (name, item_len, strlen (symname));    /* We would inherit the default ACL here, but symlinks don't get ACLs */    journal_begin(&th, parent_dir->i_sb, jbegin_count) ;    retval = reiserfs_new_inode (&th, parent_dir, mode, name, strlen (symname),                                  dentry, inode);    reiserfs_kfree (name, item_len, parent_dir->i_sb);    if (retval) { /* reiserfs_new_inode iputs for us */	goto out_failed;    }    reiserfs_update_inode_transaction(inode) ;    reiserfs_update_inode_transaction(parent_dir) ;    inode->i_op = &reiserfs_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, parent_dir, dentry->d_name.name,                                  dentry->d_name.len, inode, 1/*visible*/);    if (retval) {	inode->i_nlink--;	reiserfs_update_sd (&th, inode);	journal_end(&th, parent_dir->i_sb, jbegin_count) ;	iput (inode);	goto out_failed;    }    d_instantiate(dentry, inode);    journal_end(&th, parent_dir->i_sb, jbegin_count) ;out_failed:    reiserfs_write_unlock(parent_dir->i_sb);    return retval;}static int reiserfs_link (struct dentry * old_dentry, struct inode * dir, struct dentry * dentry){    int retval;    struct inode *inode = old_dentry->d_inode;    struct reiserfs_transaction_handle th ;    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;     reiserfs_write_lock(dir->i_sb);    if (inode->i_nlink >= REISERFS_LINK_MAX) {	//FIXME: sd_nlink is 32 bit for new files	reiserfs_write_unlock(dir->i_sb);	return -EMLINK;    }    if (inode->i_nlink == 0) {        return -ENOENT;    }    /* inc before scheduling so reiserfs_unlink knows we are here */    inode->i_nlink++;    journal_begin(&th, dir->i_sb, jbegin_count) ;    /* 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) {	inode->i_nlink--;	journal_end(&th, dir->i_sb, jbegin_count) ;	reiserfs_write_unlock(dir->i_sb);	return retval;    }    inode->i_ctime = CURRENT_TIME;    reiserfs_update_sd (&th, inode);    atomic_inc(&inode->i_count) ;    d_instantiate(dentry, inode);    journal_end(&th, dir->i_sb, jbegin_count) ;    reiserfs_write_unlock(dir->i_sb);    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 (NULL, "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 (NULL, "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;}/*  * 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_dentry_inode;    struct reiserfs_transaction_handle th ;    int jbegin_count ;     umode_t old_inode_mode;    unsigned long savelink = 1;    struct timespec ctime;    /* three balancings: (1) old name removal, (2) new name insertion       and (3) maybe "save" link insertion       stat data updates: (1) old directory,       (2) new directory and (3) maybe old object stat data (when it is       directory) and (4) maybe stat data of object to which new entry       pointed initially and (5) maybe block containing ".." of       renamed directory */    jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 5;    old_inode = old_dentry->d_inode;    new_dentry_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 = NULL;    reiserfs_write_lock(old_dir->i_sb);    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 == IO_ERROR) {	reiserfs_write_unlock(old_dir->i_sb);	return -EIO;    }    if (retval != NAME_FOUND || old_de.de_objectid != old_inode->i_ino) {	reiserfs_write_unlock(old_dir->i_sb);	return -ENOENT;    }    old_inode_mode = old_inode->i_mode;    if (S_ISDIR(old_inode_mode)) {	// make sure, that directory being renamed has correct ".." 	// and that its new parent directory has not too many links	// already	if (new_dentry_inode) {	    if (!reiserfs_empty_dir(new_dentry_inode)) {		reiserfs_write_unlock(old_dir->i_sb);		return -ENOTEMPTY;	    }	}		/* directory is renamed, its parent directory will be changed, 	** so find ".." entry 	*/	dot_dot_de.de_gen_number_bit_string = NULL;	retval = reiserfs_find_entry (old_inode, "..", 2, &dot_dot_entry_path, &dot_dot_de);	pathrelse (&dot_dot_entry_path);	if (retval != NAME_FOUND) {	    reiserfs_write_unlock(old_dir->i_sb);	    return -EIO;	}	/* inode number of .. must equal old_dir->i_ino */	if (dot_dot_de.de_objectid != old_dir->i_ino) {	    reiserfs_write_unlock(old_dir->i_sb);	    return -EIO;	}    }    journal_begin(&th, old_dir->i_sb, jbegin_count) ;    /* 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) {	if (!new_dentry_inode) {	    reiserfs_panic (old_dir->i_sb,			    "vs-7050: new entry is found, new inode == 0\n");	}    } else if (retval) {	journal_end(&th, old_dir->i_sb, jbegin_count) ;	reiserfs_write_unlock(old_dir->i_sb);	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_dentry_inode) 	reiserfs_update_inode_transaction(new_dentry_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 = NULL;	retval = reiserfs_find_entry (new_dir, new_dentry->d_name.name, new_dentry->d_name.len, 				      &new_entry_path, &new_de);	// reiserfs_add_entry should not return IO_ERROR, because it is called with essentially same parameters from        // reiserfs_add_entry above, and we'll catch any i/o errors before we get here.	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_dentry_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_mode))		reiserfs_restore_prepared_buffer (old_inode->i_sb, dot_dot_de.de_bh);	    continue;	}	if (S_ISDIR(old_inode_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_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);    ctime = CURRENT_TIME;    old_dir->i_ctime = old_dir->i_mtime = ctime;    new_dir->i_ctime = new_dir->i_mtime = ctime;    /* thanks to Alex Adriaanse <alex_a@caltech.edu> for patch which adds ctime update of       renamed object */    old_inode->i_ctime = ctime;    if (new_dentry_inode) {	// adjust link number of the victim	if (S_ISDIR(new_dentry_inode->i_mode)) {	    new_dentry_inode->i_nlink  = 0;	} else {	    new_dentry_inode->i_nlink--;	}	new_dentry_inode->i_ctime = ctime;	savelink = new_dentry_inode->i_nlink;    }    if (S_ISDIR(old_inode_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_dentry_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 (old_dir->i_sb, "vs-7060: reiserfs_rename: couldn't not cut old name. Fsck later?");    old_dir->i_size -= DEH_SIZE + old_de.de_entrylen;    reiserfs_update_sd (&th, old_dir);    reiserfs_update_sd (&th, new_dir);    reiserfs_update_sd (&th, old_inode);    if (new_dentry_inode) {	if (savelink == 0)	    add_save_link (&th, new_dentry_inode, 0/* not truncate */);	reiserfs_update_sd (&th, new_dentry_inode);    }    journal_end(&th, old_dir->i_sb, jbegin_count) ;    reiserfs_write_unlock(old_dir->i_sb);    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,    .setattr    = reiserfs_setattr,    .setxattr   = reiserfs_setxattr,    .getxattr   = reiserfs_getxattr,    .listxattr  = reiserfs_listxattr,    .removexattr = reiserfs_removexattr,    .permission     = reiserfs_permission,};/* * symlink operations.. same as page_symlink_inode_operations, with xattr * stuff added */struct inode_operations reiserfs_symlink_inode_operations = {    .readlink       = generic_readlink,    .follow_link    = page_follow_link_light,    .put_link       = page_put_link,    .setattr        = reiserfs_setattr,    .setxattr       = reiserfs_setxattr,    .getxattr       = reiserfs_getxattr,    .listxattr      = reiserfs_listxattr,    .removexattr    = reiserfs_removexattr,    .permission     = reiserfs_permission,};/* * special file operations.. just xattr/acl stuff */struct inode_operations reiserfs_special_inode_operations = {    .setattr        = reiserfs_setattr,    .setxattr       = reiserfs_setxattr,    .getxattr       = reiserfs_getxattr,    .listxattr      = reiserfs_listxattr,    .removexattr    = reiserfs_removexattr,    .permission     = reiserfs_permission,};

⌨️ 快捷键说明

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