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

📄 ext3-inode-version-2.6-sles10.patch

📁 非常经典的一个分布式系统
💻 PATCH
字号:
Index: linux-2.6.16-sles10/fs/ext3/inode.c===================================================================--- linux-2.6.16-sles10.orig/fs/ext3/inode.c+++ linux-2.6.16-sles10/fs/ext3/inode.c@@ -2561,6 +2561,13 @@ void ext3_read_inode(struct inode * inod 	EXT3_INODE_GET_XTIME(i_atime, inode, raw_inode); 	EXT3_EINODE_GET_XTIME(i_crtime, ei, raw_inode); +	ei->i_fs_version = le32_to_cpu(raw_inode->i_disk_version);+	if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) {+		if (EXT3_FITS_IN_INODE(raw_inode, ei, i_version_hi))+			ei->i_fs_version |= (__u64)(le32_to_cpu(raw_inode->i_version_hi))+									 << 32;+	}+ 	if (S_ISREG(inode->i_mode)) { 		inode->i_op = &ext3_file_inode_operations; 		inode->i_fop = &ext3_file_operations;@@ -2699,8 +2706,14 @@ static int ext3_do_update_inode(handle_t 	} else for (block = 0; block < EXT3_N_BLOCKS; block++) 		raw_inode->i_block[block] = ei->i_data[block]; -	if (ei->i_extra_isize)+	raw_inode->i_disk_version = cpu_to_le32(ei->i_fs_version);+	if (ei->i_extra_isize) {+		if (EXT3_FITS_IN_INODE(raw_inode, ei, i_version_hi)) {+			raw_inode->i_version_hi = cpu_to_le32(ei->i_fs_version+									>> 32);+		} 		raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize);+	}  	BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); 	rc = ext3_journal_dirty_metadata(handle, bh);@@ -2974,10 +2987,32 @@ ext3_reserve_inode_write(handle_t *handl int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode) { 	struct ext3_iloc iloc;-	int err;+	int err, ret;+	static int expand_message;  	might_sleep(); 	err = ext3_reserve_inode_write(handle, inode, &iloc);+	if (EXT3_I(inode)->i_extra_isize <+	    EXT3_SB(inode->i_sb)->s_want_extra_isize &&+	    !(EXT3_I(inode)->i_state & EXT3_STATE_NO_EXPAND)) {+		/* We need extra buffer credits since we may write into EA block+		 * with this same handle */+		if ((ext3_journal_extend(handle,+			     EXT3_DATA_TRANS_BLOCKS(inode->i_sb))) == 0) {+			ret = ext3_expand_extra_isize(inode,+  					EXT3_SB(inode->i_sb)->s_want_extra_isize,+					iloc, handle);+			if (ret) {+				EXT3_I(inode)->i_state |= EXT3_STATE_NO_EXPAND;+				if (!expand_message) {+					ext3_warning(inode->i_sb, __FUNCTION__,+					"Unable to expand inode %lu. Delete some"+					" EAs or run e2fsck.", inode->i_ino);+					expand_message = 1;+				}+			}+		}+	} 	if (!err) 		err = ext3_mark_iloc_dirty(handle, inode, &iloc); 	return err;Index: linux-2.6.16-sles10/include/linux/ext3_fs.h===================================================================--- linux-2.6.16-sles10.orig/include/linux/ext3_fs.h+++ linux-2.6.16-sles10/include/linux/ext3_fs.h@@ -227,6 +227,7 @@ struct ext3_group_desc #define EXT3_STATE_JDATA		0x00000001 /* journaled data exists */ #define EXT3_STATE_NEW			0x00000002 /* inode is newly created */ #define EXT3_STATE_XATTR		0x00000004 /* has in-inode xattrs */+#define EXT3_STATE_NO_EXPAND		0x00000008 /* No space for expansion */  /* Used to pass group descriptor data when online resize is done */ struct ext3_new_group_input {@@ -303,7 +304,7 @@ struct ext3_inode { 	__le32	i_flags;	/* File flags */ 	union { 		struct {-			__u32  l_i_reserved1;+			__u32  l_i_version; 		} linux1; 		struct { 			__u32  h_i_translator;@@ -348,6 +349,7 @@ struct ext3_inode { 	__le32  i_atime_extra;  /* extra Access time      (nsec << 2 | epoch) */ 	__le32  i_crtime;       /* File Creation time */ 	__le32  i_crtime_extra; /* extra File Creation time (nsec << 2 | epoch) */+	__le32	i_version_hi;	/* high 32 bits for 64-bit version */ };  #define i_size_high	i_dir_acl@@ -410,6 +412,8 @@ do {								     	 \ 				      raw_inode->xtime ## _extra);       \ } while (0) +#define i_disk_version osd1.linux1.l_i_version+ #if defined(__KERNEL__) || defined(__linux__) #define i_reserved1	osd1.linux1.l_i_reserved1 #define i_frag		osd2.linux2.l_i_fragIndex: linux-2.6.16-sles10/include/linux/ext3_fs_i.h===================================================================--- linux-2.6.16-sles10.orig/include/linux/ext3_fs_i.h+++ linux-2.6.16-sles10/include/linux/ext3_fs_i.h@@ -20,6 +20,8 @@ #include <linux/rbtree.h> #include <linux/seqlock.h> +#define HAVE_DISK_INODE_VERSION+ struct ext3_reserve_window { 	__u32			_rsv_start;	/* First byte reserved */ 	__u32			_rsv_end;	/* Last byte reserved or 0 */@@ -142,6 +144,8 @@ struct ext3_inode_info { 	spinlock_t i_prealloc_lock;  	void *i_filterdata;++	__u64 i_fs_version; };  #endif	/* _LINUX_EXT3_FS_I */Index: linux-2.6.16-sles10/fs/ext3/xattr.c===================================================================--- linux-2.6.16-sles10.orig/fs/ext3/xattr.c+++ linux-2.6.16-sles10/fs/ext3/xattr.c@@ -505,6 +505,20 @@ ext3_xattr_release_block(handle_t *handl 	} } +static inline size_t ext3_xattr_free_space(struct ext3_xattr_entry *last,+				    size_t *min_offs, void *base, int *total)+{+	for (; !IS_LAST_ENTRY(last); last = EXT3_XATTR_NEXT(last)) {+		*total += EXT3_XATTR_LEN(last->e_name_len);+		if (!last->e_value_block && last->e_value_size) {+			size_t offs = le16_to_cpu(last->e_value_offs);+			if (offs < *min_offs)+				*min_offs = offs;+		}+	}+	return (*min_offs - ((void *)last - base) - sizeof(__u32));+}+ struct ext3_xattr_info { 	int name_index; 	const char *name;@@ -944,13 +958,18 @@ ext3_xattr_set_handle(handle_t *handle,  	struct ext3_xattr_block_find bs = { 		.s = { .not_found = -ENODATA, }, 	};+	unsigned long no_expand; 	int error;  	if (!name) 		return -EINVAL; 	if (strlen(name) > 255) 		return -ERANGE;+ 	down_write(&EXT3_I(inode)->xattr_sem);+	no_expand = EXT3_I(inode)->i_state & EXT3_STATE_NO_EXPAND;+	EXT3_I(inode)->i_state |= EXT3_STATE_NO_EXPAND;+ 	error = ext3_get_inode_loc(inode, &is.iloc); 	if (error) 		goto cleanup;@@ -1007,7 +1026,10 @@ ext3_xattr_set_handle(handle_t *handle,  	if (!error) { 		ext3_xattr_update_super_block(handle, inode->i_sb); 		inode->i_ctime = ext3_current_time(inode);+ 		error = ext3_mark_iloc_dirty(handle, inode, &is.iloc);+		if (!value)+			EXT3_I(inode)->i_state &= ~EXT3_STATE_NO_EXPAND; 		/* 		 * The bh is consumed by ext3_mark_iloc_dirty, even with 		 * error != 0.@@ -1020,6 +1042,8 @@ ext3_xattr_set_handle(handle_t *handle,  cleanup: 	brelse(is.iloc.bh); 	brelse(bs.bh);+	if (no_expand == 0)+		EXT3_I(inode)->i_state &= ~EXT3_STATE_NO_EXPAND; 	up_write(&EXT3_I(inode)->xattr_sem); 	return error; }@@ -1059,6 +1083,249 @@ retry: 	return error; } +static void ext3_xattr_shift_entries(struct ext3_xattr_entry *entry,+				     int value_offs_shift, void *to,+				     void *from, size_t n, int blocksize)+{+	struct ext3_xattr_entry *last = entry;+	int new_offs;++	/* Adjust the value offsets of the entries */+	for (; !IS_LAST_ENTRY(last); last = EXT3_XATTR_NEXT(last)) {+		if (!last->e_value_block && last->e_value_size) {+			new_offs = le16_to_cpu(last->e_value_offs) ++							value_offs_shift;+			BUG_ON(new_offs + le32_to_cpu(last->e_value_size) >+			       blocksize);+			last->e_value_offs = cpu_to_le16(new_offs);+		}+	}+	/* Shift the entries by n bytes */+	memmove(to, from, n);+}++/* Expand an inode by new_extra_isize bytes.+ * Returns 0 on success or negative error number on failure.+ */+int ext3_expand_extra_isize(struct inode *inode, int new_extra_isize,+			    struct ext3_iloc iloc, handle_t *handle)+{+	struct ext3_inode *raw_inode;+	struct ext3_xattr_ibody_header *header;+	struct ext3_xattr_entry *entry, *last, *first;+	struct buffer_head *bh = NULL;+	struct ext3_xattr_ibody_find *is = NULL;+	struct ext3_xattr_block_find *bs = NULL;+	char *buffer = NULL, *b_entry_name = NULL;+	size_t min_offs, free;+	int total_ino, total_blk;+	void *base, *start, *end;+	int extra_isize = 0, error = 0, tried_min_extra_isize = 0;+	int s_min_extra_isize = EXT3_SB(inode->i_sb)->s_es->s_min_extra_isize;++	down_write(&EXT3_I(inode)->xattr_sem);++retry:+	if (EXT3_I(inode)->i_extra_isize >= new_extra_isize) {+		up_write(&EXT3_I(inode)->xattr_sem);+		return 0;+	}++	raw_inode = ext3_raw_inode(&iloc);++	header = IHDR(inode, raw_inode);+	entry = IFIRST(header);++	/* No extended attributes present */+	if (!(EXT3_I(inode)->i_state & EXT3_STATE_XATTR) ||+	    header->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC)) {+		memset((void *)raw_inode + EXT3_GOOD_OLD_INODE_SIZE, 0,+		       new_extra_isize);+		EXT3_I(inode)->i_extra_isize = new_extra_isize;+		goto cleanup;+	}++	/*+	 * Check if enough free space is available in the inode to shift the+	 * entries ahead by new_extra_isize.+	 */++	base = start = entry;+	end = (void *)raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;+	min_offs = end - base;+	last = entry;+	total_ino = sizeof(struct ext3_xattr_ibody_header);++	free = ext3_xattr_free_space(last, &min_offs, base, &total_ino);+	if (free >= new_extra_isize) {+		entry = IFIRST(header);+		ext3_xattr_shift_entries(entry,	EXT3_I(inode)->i_extra_isize -+				new_extra_isize, (void *)raw_inode ++				EXT3_GOOD_OLD_INODE_SIZE + new_extra_isize,+				(void *)header, total_ino,+				inode->i_sb->s_blocksize);+		EXT3_I(inode)->i_extra_isize = new_extra_isize;+		error = 0;+		goto cleanup;+	}++	/*+	 * Enough free space isn't available in the inode, check if+	 * EA block can hold new_extra_isize bytes.+	 */+	if (EXT3_I(inode)->i_file_acl) {+		bh = sb_bread(inode->i_sb, EXT3_I(inode)->i_file_acl);+		error = -EIO;+		if (!bh)+			goto cleanup;+		if (ext3_xattr_check_block(bh)) {+			ext3_error(inode->i_sb, __FUNCTION__,+				"inode %lu: bad block %d", inode->i_ino,+				EXT3_I(inode)->i_file_acl);+			error = -EIO;+			goto cleanup;+		}+		base = BHDR(bh);+		first = BFIRST(bh);+		end = bh->b_data + bh->b_size;+		min_offs = end - base;+		free = ext3_xattr_free_space(first, &min_offs, base,+					     &total_blk);+		if (free < new_extra_isize) {+			if (!tried_min_extra_isize && s_min_extra_isize) {+				tried_min_extra_isize++;+				new_extra_isize = s_min_extra_isize;+				goto retry;+			}+			error = -1;+			goto cleanup;+		}+	} else {+		free = inode->i_sb->s_blocksize;+	}++	while (new_extra_isize > 0) {+		size_t offs, size, entry_size;+		struct ext3_xattr_entry *small_entry = NULL;+		struct ext3_xattr_info i = {+			.value = NULL,+			.value_len = 0,+		};+		unsigned int total_size, shift_bytes, temp = ~0U;++		is = (struct ext3_xattr_ibody_find *) kmalloc(sizeof(struct+					 ext3_xattr_ibody_find), GFP_KERNEL);+		bs = (struct ext3_xattr_block_find *) kmalloc(sizeof(struct+					 ext3_xattr_block_find), GFP_KERNEL);+		memset((void *)is, 0, sizeof(struct ext3_xattr_ibody_find));+		memset((void *)bs, 0, sizeof(struct ext3_xattr_block_find));++		is->s.not_found = bs->s.not_found = -ENODATA;+		is->iloc.bh = NULL;+		bs->bh = NULL;++		last = IFIRST(header);+		/* Find the entry best suited to be pushed into EA block */+		entry = NULL;+		for (; !IS_LAST_ENTRY(last); last = EXT3_XATTR_NEXT(last)) {+			total_size = EXT3_XATTR_SIZE(le32_to_cpu(last->e_value_size)) ++	    			    	EXT3_XATTR_LEN(last->e_name_len);+			if (total_size <= free && total_size < temp) {+				if (total_size < new_extra_isize) {+					small_entry = last;+				} else {+					entry = last;+					temp = total_size;+				}+			}+		}++		if (entry == NULL) {+			if (small_entry) {+				entry = small_entry;+			} else {+				if (!tried_min_extra_isize &&+				    s_min_extra_isize) {+					tried_min_extra_isize++;+					new_extra_isize = s_min_extra_isize;+					goto retry;+				}+				error = -1;+				goto cleanup;+			}+		}+		offs = le16_to_cpu(entry->e_value_offs);+		size = le32_to_cpu(entry->e_value_size);+		entry_size = EXT3_XATTR_LEN(entry->e_name_len);+		i.name_index = entry->e_name_index,+		buffer = kmalloc(EXT3_XATTR_SIZE(size), GFP_KERNEL);+		b_entry_name = kmalloc(entry->e_name_len + 1, GFP_KERNEL);+		/* Save the entry name and the entry value */+		memcpy((void *)buffer, (void *)IFIRST(header) + offs,+		       EXT3_XATTR_SIZE(size));+		memcpy((void *)b_entry_name, (void *)entry->e_name,+		       entry->e_name_len);+		b_entry_name[entry->e_name_len] = '\0';+		i.name = b_entry_name;++		error = ext3_get_inode_loc(inode, &is->iloc);+		if (error)+			goto cleanup;++		error = ext3_xattr_ibody_find(inode, &i, is);+		if (error)+			goto cleanup;++		/* Remove the chosen entry from the inode */+		error = ext3_xattr_ibody_set(handle, inode, &i, is);++		entry = IFIRST(header);+		if (entry_size + EXT3_XATTR_SIZE(size) >= new_extra_isize)+			shift_bytes = new_extra_isize;+		else+			shift_bytes = entry_size + size;+		/* Adjust the offsets and shift the remaining entries ahead */+		ext3_xattr_shift_entries(entry, EXT3_I(inode)->i_extra_isize -+			shift_bytes, (void *)raw_inode ++			EXT3_GOOD_OLD_INODE_SIZE + extra_isize + shift_bytes,+			(void *)header, total_ino - entry_size,+			inode->i_sb->s_blocksize);++		extra_isize += shift_bytes;+		new_extra_isize -= shift_bytes;+		EXT3_I(inode)->i_extra_isize = extra_isize;++		i.name = b_entry_name;+		i.value = buffer;+		i.value_len = cpu_to_le32(size);+		error = ext3_xattr_block_find(inode, &i, bs);+		if (error)+			goto cleanup;++		/* Add entry which was removed from the inode into the block */+		error = ext3_xattr_block_set(handle, inode, &i, bs);+		if (error)+			goto cleanup;+	}++cleanup:+	if (b_entry_name)+		kfree(b_entry_name);+	if (buffer)+		kfree(buffer);+	if (is) {+		brelse(is->iloc.bh);+		kfree(is);+	}+	if (bs)+		kfree(bs);+	brelse(bh);+	up_write(&EXT3_I(inode)->xattr_sem);+	return error;+}+++ /*  * ext3_xattr_delete_inode()  *Index: linux-2.6.16-sles10/fs/ext3/xattr.h===================================================================--- linux-2.6.16-sles10.orig/fs/ext3/xattr.h+++ linux-2.6.16-sles10/fs/ext3/xattr.h@@ -75,6 +75,9 @@ extern int ext3_xattr_set_handle(handle_ extern void ext3_xattr_delete_inode(handle_t *, struct inode *); extern void ext3_xattr_put_super(struct super_block *); +int ext3_expand_extra_isize(struct inode *inode, int new_extra_isize,+			    struct ext3_iloc iloc, handle_t *handle);+ extern int init_ext3_xattr(void); extern void exit_ext3_xattr(void); 

⌨️ 快捷键说明

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