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

📄 inode.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* either due to i/o error or a stale NFS handle */	iput (inode);	inode = 0;    }    return inode;}struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, __u32 *data,				     int len, int fhtype, int parent) {    struct cpu_key key ;    struct inode *inode = NULL ;    struct list_head *lp;    struct dentry *result;    /* fhtype happens to reflect the number of u32s encoded.     * due to a bug in earlier code, fhtype might indicate there     * are more u32s then actually fitted.     * so if fhtype seems to be more than len, reduce fhtype.     * Valid types are:     *   2 - objectid + dir_id - legacy support     *   3 - objectid + dir_id + generation     *   4 - objectid + dir_id + objectid and dirid of parent - legacy     *   5 - objectid + dir_id + generation + objectid and dirid of parent     *   6 - as above plus generation of directory     * 6 does not fit in NFSv2 handles     */    if (fhtype > len) {	    if (fhtype != 6 || len != 5)		    printk(KERN_WARNING "nfsd/reiserfs, fhtype=%d, len=%d - odd\n",			   fhtype, len);	    fhtype = 5;    }    if (fhtype < 2 || (parent && fhtype < 4)) 	goto out ;    if (! parent) {	    /* this works for handles from old kernels because the default	    ** reiserfs generation number is the packing locality.	    */	    key.on_disk_key.k_objectid = data[0] ;	    key.on_disk_key.k_dir_id = data[1] ;	    inode = reiserfs_iget(sb, &key) ;	    if (inode && !IS_ERR(inode) && (fhtype == 3 || fhtype >= 5) &&		data[2] != inode->i_generation) {		    iput(inode) ;		    inode = NULL ;	    }    } else {	    key.on_disk_key.k_objectid = data[fhtype>=5?3:2] ;	    key.on_disk_key.k_dir_id = data[fhtype>=5?4:3] ;	    inode = reiserfs_iget(sb, &key) ;	    if (inode && !IS_ERR(inode) && fhtype == 6 &&		data[5] != inode->i_generation) {		    iput(inode) ;		    inode = NULL ;	    }    }out:    if (IS_ERR(inode))	return ERR_PTR(PTR_ERR(inode));    if (!inode)        return ERR_PTR(-ESTALE) ;    /* now to find a dentry.     * If possible, get a well-connected one     */    spin_lock(&dcache_lock);    for (lp = inode->i_dentry.next; lp != &inode->i_dentry ; lp=lp->next) {	    result = list_entry(lp,struct dentry, d_alias);	    if (! (result->d_flags & DCACHE_NFSD_DISCONNECTED)) {		    dget_locked(result);		    result->d_vfs_flags |= DCACHE_REFERENCED;		    spin_unlock(&dcache_lock);		    iput(inode);		    return result;	    }    }    spin_unlock(&dcache_lock);    result = d_alloc_root(inode);    if (result == NULL) {	    iput(inode);	    return ERR_PTR(-ENOMEM);    }    result->d_flags |= DCACHE_NFSD_DISCONNECTED;    return result;}int reiserfs_dentry_to_fh(struct dentry *dentry, __u32 *data, int *lenp, int need_parent) {    struct inode *inode = dentry->d_inode ;    int maxlen = *lenp;        if (maxlen < 3)        return 255 ;    data[0] = inode->i_ino ;    data[1] = le32_to_cpu(INODE_PKEY (inode)->k_dir_id) ;    data[2] = inode->i_generation ;    *lenp = 3 ;    /* no room for directory info? return what we've stored so far */    if (maxlen < 5 || ! need_parent)        return 3 ;    inode = dentry->d_parent->d_inode ;    data[3] = inode->i_ino ;    data[4] = le32_to_cpu(INODE_PKEY (inode)->k_dir_id) ;    *lenp = 5 ;    if (maxlen < 6)	    return 5 ;    data[5] = inode->i_generation ;    *lenp = 6 ;    return 6 ;}//// initially this function was derived from minix or ext2's analog and// evolved as the prototype did///* looks for stat data, then copies fields to it, marks the buffer   containing stat data as dirty *//* reiserfs inodes are never really dirty, since the dirty inode call** always logs them.  This call allows the VFS inode marking routines** to properly mark inodes for datasync and such, but only actually** does something when called for a synchronous update.*/void reiserfs_write_inode (struct inode * inode, int do_sync) {    struct reiserfs_transaction_handle th ;    int jbegin_count = 1 ;    if (inode->i_sb->s_flags & MS_RDONLY) {        reiserfs_warning("clm-6005: writing inode %lu on readonly FS\n", 	                  inode->i_ino) ;        return ;    }    /* memory pressure can sometimes initiate write_inode calls with sync == 1,    ** these cases are just when the system needs ram, not when the     ** inode needs to reach disk for safety, and they can safely be    ** ignored because the altered inode has already been logged.    */    if (do_sync && !(current->flags & PF_MEMALLOC)) {	lock_kernel() ;	journal_begin(&th, inode->i_sb, jbegin_count) ;	reiserfs_update_sd (&th, inode);	journal_end_sync(&th, inode->i_sb, jbegin_count) ;	unlock_kernel() ;    }}/* FIXME: no need any more. right? */int reiserfs_sync_inode (struct reiserfs_transaction_handle *th, struct inode * inode){  int err = 0;  reiserfs_update_sd (th, inode);  return err;}/* stat data of new object is inserted already, this inserts the item   containing "." and ".." entries */static int reiserfs_new_directory (struct reiserfs_transaction_handle *th, 				   struct item_head * ih, struct path * path,				   const struct inode * dir){    struct super_block * sb = th->t_super;    char empty_dir [EMPTY_DIR_SIZE];    char * body = empty_dir;    struct cpu_key key;    int retval;        _make_cpu_key (&key, KEY_FORMAT_3_5, le32_to_cpu (ih->ih_key.k_dir_id),		   le32_to_cpu (ih->ih_key.k_objectid), DOT_OFFSET, TYPE_DIRENTRY, 3/*key length*/);        /* compose item head for new item. Directories consist of items of       old type (ITEM_VERSION_1). Do not set key (second arg is 0), it       is done by reiserfs_new_inode */    if (old_format_only (sb)) {	make_le_item_head (ih, 0, KEY_FORMAT_3_5, DOT_OFFSET, TYPE_DIRENTRY, EMPTY_DIR_SIZE_V1, 2);		make_empty_dir_item_v1 (body, ih->ih_key.k_dir_id, ih->ih_key.k_objectid,				INODE_PKEY (dir)->k_dir_id, 				INODE_PKEY (dir)->k_objectid );    } else {	make_le_item_head (ih, 0, KEY_FORMAT_3_5, DOT_OFFSET, TYPE_DIRENTRY, EMPTY_DIR_SIZE, 2);		make_empty_dir_item (body, ih->ih_key.k_dir_id, ih->ih_key.k_objectid,		   		INODE_PKEY (dir)->k_dir_id, 		   		INODE_PKEY (dir)->k_objectid );    }        /* look for place in the tree for new item */    retval = search_item (sb, &key, path);    if (retval == IO_ERROR) {	reiserfs_warning ("vs-13080: reiserfs_new_directory: "			  "i/o failure occurred creating new directory\n");	return -EIO;    }    if (retval == ITEM_FOUND) {	pathrelse (path);	reiserfs_warning ("vs-13070: reiserfs_new_directory: "			  "object with this key exists (%k)", &(ih->ih_key));	return -EEXIST;    }    /* insert item, that is empty directory item */    return reiserfs_insert_item (th, path, &key, ih, body);}/* stat data of object has been inserted, this inserts the item   containing the body of symlink */static int reiserfs_new_symlink (struct reiserfs_transaction_handle *th, 				 struct item_head * ih,				 struct path * path, const char * symname, int item_len){    struct super_block * sb = th->t_super;    struct cpu_key key;    int retval;    _make_cpu_key (&key, KEY_FORMAT_3_5, 		   le32_to_cpu (ih->ih_key.k_dir_id), 		   le32_to_cpu (ih->ih_key.k_objectid),		   1, TYPE_DIRECT, 3/*key length*/);    make_le_item_head (ih, 0, KEY_FORMAT_3_5, 1, TYPE_DIRECT, item_len, 0/*free_space*/);    /* look for place in the tree for new item */    retval = search_item (sb, &key, path);    if (retval == IO_ERROR) {	reiserfs_warning ("vs-13080: reiserfs_new_symlinik: "			  "i/o failure occurred creating new symlink\n");	return -EIO;    }    if (retval == ITEM_FOUND) {	pathrelse (path);	reiserfs_warning ("vs-13080: reiserfs_new_symlink: "			  "object with this key exists (%k)", &(ih->ih_key));	return -EEXIST;    }    /* insert item, that is body of symlink */    return reiserfs_insert_item (th, path, &key, ih, symname);}/* inserts the stat data into the tree, and then calls   reiserfs_new_directory (to insert ".", ".." item if new object is   directory) or reiserfs_new_symlink (to insert symlink body if new   object is symlink) or nothing (if new object is regular file) */struct inode * reiserfs_new_inode (struct reiserfs_transaction_handle *th,				   const struct inode * dir, int mode, 				   const char * symname, 				   int i_size, /* 0 for regular, EMTRY_DIR_SIZE for dirs,						  strlen (symname) for symlinks)*/				   struct dentry *dentry, struct inode *inode, int * err){    struct super_block * sb;    INITIALIZE_PATH (path_to_key);    struct cpu_key key;    struct item_head ih;    struct stat_data sd;    int retval;      if (!dir || !dir->i_nlink) {	*err = -EPERM;	iput(inode) ;	return NULL;    }    sb = dir->i_sb;    inode->i_flags = 0;//inode->i_sb->s_flags;    /* item head of new item */    ih.ih_key.k_dir_id = INODE_PKEY (dir)->k_objectid;    ih.ih_key.k_objectid = cpu_to_le32 (reiserfs_get_unused_objectid (th));    if (!ih.ih_key.k_objectid) {	iput(inode) ;	*err = -ENOMEM;	return NULL;    }    if (old_format_only (sb))      /* not a perfect generation count, as object ids can be reused, but this      ** is as good as reiserfs can do right now.      ** note that the private part of inode isn't filled in yet, we have      ** to use the directory.      */      inode->i_generation = le32_to_cpu (INODE_PKEY (dir)->k_objectid);    else#if defined( USE_INODE_GENERATION_COUNTER )      inode->i_generation = 	le32_to_cpu( sb -> u.reiserfs_sb.s_rs -> s_inode_generation );#else      inode->i_generation = ++event;#endif    if (old_format_only (sb))	make_le_item_head (&ih, 0, KEY_FORMAT_3_5, SD_OFFSET, TYPE_STAT_DATA, SD_V1_SIZE, MAX_US_INT);    else	make_le_item_head (&ih, 0, KEY_FORMAT_3_6, SD_OFFSET, TYPE_STAT_DATA, SD_SIZE, MAX_US_INT);    /* key to search for correct place for new stat data */    _make_cpu_key (&key, KEY_FORMAT_3_6, le32_to_cpu (ih.ih_key.k_dir_id),		   le32_to_cpu (ih.ih_key.k_objectid), SD_OFFSET, TYPE_STAT_DATA, 3/*key length*/);    /* find proper place for inserting of stat data */    retval = search_item (sb, &key, &path_to_key);    if (retval == IO_ERROR) {	iput (inode);	*err = -EIO;	return NULL;    }    if (retval == ITEM_FOUND) {	pathrelse (&path_to_key);	iput (inode);	*err = -EEXIST;	return NULL;    }    /* fill stat data */    inode->i_mode = mode;    inode->i_nlink = (S_ISDIR (mode) ? 2 : 1);    inode->i_uid = current->fsuid;    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;    inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;    inode->i_size = i_size;    inode->i_blocks = (inode->i_size + 511) >> 9;    inode->u.reiserfs_i.i_first_direct_byte = S_ISLNK(mode) ? 1 :       U32_MAX/*NO_BYTES_IN_DIRECT_ITEM*/;    INIT_LIST_HEAD(&inode->u.reiserfs_i.i_prealloc_list) ;    if (old_format_only (sb)) {	if (inode->i_uid & ~0xffff || inode->i_gid & ~0xffff) {	    pathrelse (&path_to_key);	    /* i_uid or i_gid is too big to be stored in stat data v3.5 */	    iput (inode);	    *err = -EINVAL;	    return NULL;	}	inode2sd_v1 (&sd, inode);    } else	inode2sd (&sd, inode);    // these do not go to on-disk stat data    inode->i_ino = le32_to_cpu (ih.ih_key.k_objectid);    inode->i_blksize = PAGE_SIZE;    inode->i_dev = sb->s_dev;      // store in in-core inode the key of stat data and version all    // object items will have (directory items will have old offset    // format, other new objects will consist of new items)    memcpy (INODE_PKEY (inode), &(ih.ih_key), KEY_SIZE);    if (old_format_only (sb) || S_ISDIR(mode) || S_ISLNK(mode))        set_inode_item_key_version (inode, KEY_FORMAT_3_5);    else        set_inode_item_key_version (inode, KEY_FORMAT_3_6);    if (old_format_only (sb))	set_inode_sd_version (inode, STAT_DATA_V1);    else	set_inode_sd_version (inode, STAT_DATA_V2);        /* insert the stat data into the tree */    retval = reiserfs_insert_item (th, &path_to_key, &key, &ih, (char *)(&sd));    if (retval) {	iput (inode);	*err = retval;	reiserfs_check_path(&path_to_key) ;	return NULL;    }    if (S_ISDIR(mode)) {	/* insert item with "." and ".." */	retval = reiserfs_new_directory (th, &ih, &path_to_key, dir);    }    if (S_ISLNK(mode)) {	/* insert body of symlink */	if (!old_format_only (sb))	    i_size = ROUND_UP(i_size);	retval = reiserfs_new_symlink (th, &ih, &path_to_key, symname, i_size);    }    if (retval) {      inode->i_nlink = 0;	iput (inode);	*err = retval;	reiserfs_check_path(&path_to_key) ;	return NULL;    }    insert_inode_hash (inode);    // we do not mark inode dirty: on disk content matches to the    // in-core one    reiserfs_check_path(&path_to_key) ;    return inode;}/*** finds the tail page in the page cache,** reads the last block in.**

⌨️ 快捷键说明

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