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

📄 namei.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 3 页
字号:
    /* 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 == IO_ERROR ) {	    return -EIO;	}        if (retval != NAME_FOUND) {	    reiserfs_warning (dir->i_sb, "zam-7002:%s: \"reiserfs_find_entry\" "			      "has returned unexpected value (%d)",			      __FUNCTION__, retval);       }	return -EEXIST;    }    gen_number = find_first_zero_bit ((unsigned long *)bit_string, MAX_GENERATION_NUMBER + 1);    if (gen_number > MAX_GENERATION_NUMBER) {      /* there is no free generation number */      reiserfs_warning (dir->i_sb, "reiserfs_add_entry: Congratulations! we have got hash function screwed up");      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 (dir->i_sb, "vs-7032: reiserfs_add_entry: "                              "entry with this key (%K) already exists",                              &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, dir, 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_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;}/* quota utility function, call if you've had to abort after calling** new_inode_init, and have not called reiserfs_new_inode yet.** This should only be called on inodes that do not hav stat data** inserted into the tree yet.*/static int drop_new_inode(struct inode *inode) {    DQUOT_DROP(inode);    make_bad_inode(inode) ;    inode->i_flags |= S_NOQUOTA;    iput(inode) ;    return 0 ;}/* utility function that does setup for reiserfs_new_inode.  ** DQUOT_ALLOC_INODE cannot be called inside a transaction, so we had** to pull some bits of reiserfs_new_inode out into this func.** Yes, the actual quota calls are missing, they are part of the quota** patch.*/static int new_inode_init(struct inode *inode, struct inode *dir, int mode) {    /* the quota init calls have to know who to charge the quota to, so    ** we have to set uid and gid here    */    inode->i_uid = current->fsuid;    inode->i_mode = mode;    if (dir->i_mode & S_ISGID) {        inode->i_gid = dir->i_gid;        if (S_ISDIR(mode))            inode->i_mode |= S_ISGID;    } else {        inode->i_gid = current->fsgid;    }    DQUOT_INIT(inode);    if (DQUOT_ALLOC_INODE(inode)) {        drop_new_inode(inode);	return -EDQUOT;    }    return 0 ;}static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode,		struct nameidata *nd){    int retval;    struct inode * inode;    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 ;    struct reiserfs_transaction_handle th ;    int locked;    if (!(inode = new_inode(dir->i_sb))) {	return -ENOMEM ;    }    retval = new_inode_init(inode, dir, mode);    if (retval)        return retval;    locked = reiserfs_cache_default_acl (dir);    reiserfs_write_lock(dir->i_sb);    if (locked)        reiserfs_write_lock_xattrs (dir->i_sb);    journal_begin(&th, dir->i_sb, jbegin_count) ;    retval = reiserfs_new_inode (&th, dir, mode, NULL, 0/*i_size*/, dentry, inode);    if (locked)        reiserfs_write_unlock_xattrs (dir->i_sb);    if (retval) {        goto out_failed;    }	    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);	journal_end(&th, dir->i_sb, jbegin_count) ;	iput (inode);	goto out_failed;    }    reiserfs_update_inode_transaction(inode) ;    reiserfs_update_inode_transaction(dir) ;    d_instantiate(dentry, inode);    journal_end(&th, dir->i_sb, jbegin_count) ;out_failed:    reiserfs_write_unlock(dir->i_sb);    return retval;}static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t rdev){    int retval;    struct inode * inode;    struct reiserfs_transaction_handle th ;    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;     int locked;    if (!new_valid_dev(rdev))	return -EINVAL;    if (!(inode = new_inode(dir->i_sb))) {	return -ENOMEM ;    }    retval = new_inode_init(inode, dir, mode);    if (retval)        return retval;    locked = reiserfs_cache_default_acl (dir);    reiserfs_write_lock(dir->i_sb);    if (locked)        reiserfs_write_lock_xattrs (dir->i_sb);    journal_begin(&th, dir->i_sb, jbegin_count) ;    retval = reiserfs_new_inode (&th, dir, mode, NULL, 0/*i_size*/, dentry, inode);    if (locked)        reiserfs_write_unlock_xattrs (dir->i_sb);    if (retval) {        goto out_failed;    }    inode->i_op = &reiserfs_special_inode_operations;    init_special_inode(inode, inode->i_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);	journal_end(&th, dir->i_sb, jbegin_count) ;	iput (inode);	goto out_failed;    }    d_instantiate(dentry, inode);    journal_end(&th, dir->i_sb, jbegin_count) ;out_failed:    reiserfs_write_unlock(dir->i_sb);    return retval;}static int reiserfs_mkdir (struct inode * dir, struct dentry *dentry, int mode){    int retval;    struct inode * inode;    struct reiserfs_transaction_handle th ;    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;     int locked;#ifdef DISPLACE_NEW_PACKING_LOCALITIES    /* set flag that new packing locality created and new blocks for the content     * of that directory are not displaced yet */    REISERFS_I(dir)->new_packing_locality = 1;#endif    mode = S_IFDIR | mode;    if (!(inode = new_inode(dir->i_sb))) {	return -ENOMEM ;    }    retval = new_inode_init(inode, dir, mode);    if (retval)        return retval;    locked = reiserfs_cache_default_acl (dir);    reiserfs_write_lock(dir->i_sb);    if (locked)        reiserfs_write_lock_xattrs (dir->i_sb);    journal_begin(&th, dir->i_sb, jbegin_count) ;    /* inc the link count now, so another writer doesn't overflow it while    ** we sleep later on.    */    INC_DIR_INODE_NLINK(dir)    retval = reiserfs_new_inode (&th, dir, mode, NULL/*symlink*/,				old_format_only (dir->i_sb) ? 				EMPTY_DIR_SIZE_V1 : EMPTY_DIR_SIZE,				dentry, inode);    if (locked)        reiserfs_write_unlock_xattrs (dir->i_sb);    if (retval) {	dir->i_nlink-- ;	goto out_failed;    }    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);	journal_end(&th, dir->i_sb, jbegin_count) ;	iput (inode);	goto out_failed;    }    // the above add_entry did not update dir's stat data    reiserfs_update_sd (&th, dir);    d_instantiate(dentry, inode);    journal_end(&th, dir->i_sb, jbegin_count) ;out_failed:    reiserfs_write_unlock(dir->i_sb);    return retval;}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 ;}static int reiserfs_rmdir (struct inode * dir, struct dentry *dentry){    int retval;    struct inode * inode;    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;    reiserfs_write_lock(dir->i_sb);    journal_begin(&th, dir->i_sb, jbegin_count) ;    de.de_gen_number_bit_string = NULL;    if ( (retval = reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path, &de)) == NAME_NOT_FOUND) {	retval = -ENOENT;	goto end_rmdir;    } else if ( retval == IO_ERROR) {	retval = -EIO;	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 )	reiserfs_warning (inode->i_sb, "%s: empty directory has nlink "			  "!= 2 (%d)", __FUNCTION__, 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);    reiserfs_update_sd (&th, dir);    /* prevent empty directory from getting lost */    add_save_link (&th, inode, 0/* not truncate */);    journal_end(&th, dir->i_sb, jbegin_count) ;    reiserfs_check_path(&path) ;    reiserfs_write_unlock(dir->i_sb);    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);    journal_end(&th, dir->i_sb, jbegin_count) ;    reiserfs_write_unlock(dir->i_sb);    return retval;	}static int reiserfs_unlink (struct inode * dir, struct dentry *dentry){    int retval;    struct inode * inode;    struct reiserfs_dir_entry de;    INITIALIZE_PATH (path);    struct reiserfs_transaction_handle th ;    int jbegin_count;    unsigned long savelink;    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;    reiserfs_write_lock(dir->i_sb);    journal_begin(&th, dir->i_sb, jbegin_count) ;	    de.de_gen_number_bit_string = NULL;    if ( (retval = reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path, &de)) == NAME_NOT_FOUND) {	retval = -ENOENT;	goto end_unlink;    } else if (retval == IO_ERROR) {	retval = -EIO;	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) {	reiserfs_warning (inode->i_sb, "%s: deleting nonexistent file "			  "(%s:%lu), %d", __FUNCTION__,			  reiserfs_bdevname (inode->i_sb), inode->i_ino,			  inode->i_nlink);	inode->i_nlink = 1;    }    inode->i_nlink--;    /*     * we schedule before doing the add_save_link call, save the link     * count so we don't race     */    savelink = inode->i_nlink;    retval = reiserfs_cut_from_item (&th, &path, &(de.de_entry_key), dir, NULL, 0);    if (retval < 0) {	inode->i_nlink++;	goto end_unlink;    }    inode->i_ctime = CURRENT_TIME;    reiserfs_update_sd (&th, inode);    dir->i_size -= (de.de_entrylen + DEH_SIZE);    dir->i_ctime = dir->i_mtime = CURRENT_TIME;    reiserfs_update_sd (&th, dir);    if (!savelink)       /* prevent file from getting lost */       add_save_link (&th, inode, 0/* not truncate */);    journal_end(&th, dir->i_sb, jbegin_count) ;    reiserfs_check_path(&path) ;    reiserfs_write_unlock(dir->i_sb);    return 0; end_unlink:

⌨️ 快捷键说明

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