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

📄 ext3-ea-in-inode-2.6-suse.patch

📁 非常经典的一个分布式系统
💻 PATCH
📖 第 1 页 / 共 2 页
字号:
+		    !memcmp(name, last->e_name, name_len)) {+			memcpy(rentry, last, sizeof(struct ext3_xattr_entry));+			ret = 0;+		} else {+			*free -= EXT3_XATTR_LEN(last->e_name_len);+			*free -= le32_to_cpu(last->e_value_size);+		}+		last = next;+	}+	+	brelse(iloc.bh);+	return ret;+}++/*+ * ext3_xattr_block_find()+ *+ * search attribute and calculate free space in EA block (if it allocated)+ * NOTE: free space includes space our attribute hold+ */+int+ext3_xattr_block_find(struct inode *inode, int name_index, const char *name,+	       struct ext3_xattr_entry *rentry, int *free)+{+	struct buffer_head *bh = NULL;+	struct ext3_xattr_entry *entry;+	char *end;+	int name_len, error = -ENOENT;++	if (!EXT3_I(inode)->i_file_acl) {+		*free = inode->i_sb->s_blocksize -+			sizeof(struct ext3_xattr_header) -+			sizeof(__u32);+		return -ENOENT;+	}+	ea_idebug(inode, "reading block %d", EXT3_I(inode)->i_file_acl);+	bh = sb_bread(inode->i_sb, EXT3_I(inode)->i_file_acl);+	if (!bh)+		return -EIO;+	ea_bdebug(bh, "b_count=%d, refcount=%d",+		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));+	end = bh->b_data + bh->b_size;+	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||+	    HDR(bh)->h_blocks != cpu_to_le32(1)) {+bad_block:	ext3_error(inode->i_sb, "ext3_xattr_get",+			"inode %ld: bad block %d", inode->i_ino,+			EXT3_I(inode)->i_file_acl);+		brelse(bh);+		return -EIO;+	}+	/* find named attribute */+	name_len = strlen(name);+	*free = bh->b_size - sizeof(__u32);++	entry = FIRST_ENTRY(bh);+	while (!IS_LAST_ENTRY(entry)) {+		struct ext3_xattr_entry *next =+			EXT3_XATTR_NEXT(entry);+		if ((char *)next >= end)+			goto bad_block;+		if (name_index == entry->e_name_index &&+		    name_len == entry->e_name_len &&+		    memcmp(name, entry->e_name, name_len) == 0) {+			memcpy(rentry, entry, sizeof(struct ext3_xattr_entry));+			error = 0;+		} else {+			*free -= EXT3_XATTR_LEN(entry->e_name_len);+			*free -= le32_to_cpu(entry->e_value_size);+		}+		entry = next;+	}+	brelse(bh);++	return error;+}++/*+ * ext3_xattr_inode_set()+ *+ * this routine add/remove/replace attribute in inode body+ */+int+ext3_xattr_ibody_set(handle_t *handle, struct inode *inode, int name_index,+		      const char *name, const void *value, size_t value_len,+		      int flags)+{+	struct ext3_xattr_entry *last, *next, *here = NULL;+	struct ext3_inode *raw_inode;+	int name_len = strlen(name);+	int esize = EXT3_XATTR_LEN(name_len);+	struct buffer_head *bh;+	int err, storage_size;+	struct ext3_iloc iloc;+	int free, min_offs;+	char *start, *end;+	+	if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE)+		return -ENOSPC;++	err = ext3_get_inode_loc(inode, &iloc, 0);+	if (err)+		return err;+	raw_inode = ext3_raw_inode(&iloc);+	bh = iloc.bh;++	storage_size = EXT3_SB(inode->i_sb)->s_inode_size -+				EXT3_GOOD_OLD_INODE_SIZE -+				EXT3_I(inode)->i_extra_isize -+				sizeof(__u32);+	start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE ++			EXT3_I(inode)->i_extra_isize;+	if ((*(__u32*) start) != EXT3_XATTR_MAGIC) {+		/* inode had no attributes before */+		*((__u32*) start) = cpu_to_le32(EXT3_XATTR_MAGIC);+	}+	start += sizeof(__u32);+	end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;+	min_offs = storage_size;+	free = storage_size - sizeof(__u32);++	last = (struct ext3_xattr_entry *) start;	+	while (!IS_LAST_ENTRY(last)) {+		next = EXT3_XATTR_NEXT(last);+		if (le32_to_cpu(last->e_value_size) > storage_size ||+				(char *) next >= end) {+			ext3_error(inode->i_sb, "ext3_xattr_ibody_set",+				"inode %ld", inode->i_ino);+			brelse(bh);+			return -EIO;+		}+		+		if (last->e_value_size) {+			int offs = le16_to_cpu(last->e_value_offs);+			if (offs < min_offs)+				min_offs = offs;+		}+		if (name_index == last->e_name_index &&+			name_len == last->e_name_len &&+			!memcmp(name, last->e_name, name_len))+			here = last;+		else {+			/* we calculate all but our attribute+			 * because it will be removed before changing */+			free -= EXT3_XATTR_LEN(last->e_name_len);+			free -= le32_to_cpu(last->e_value_size);+		}+		last = next;+	}++	if (value && (esize + value_len > free)) {+		brelse(bh);+		return -ENOSPC;+	}+	+	err = ext3_reserve_inode_write(handle, inode, &iloc);+	if (err) {+		brelse(bh);	+		return err;+	}++	if (here) {+		/* time to remove old value */+		struct ext3_xattr_entry *e;+		int size = le32_to_cpu(here->e_value_size);+		int border = le16_to_cpu(here->e_value_offs);+		char *src;++		/* move tail */+		memmove(start + min_offs + size, start + min_offs,+				border - min_offs);++		/* recalculate offsets */+		e = (struct ext3_xattr_entry *) start;+		while (!IS_LAST_ENTRY(e)) {+			struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(e);+			int offs = le16_to_cpu(e->e_value_offs);+			if (offs < border)+				e->e_value_offs =+					cpu_to_le16(offs + size);+			e = next;+		}+		min_offs += size;++		/* remove entry */+		border = EXT3_XATTR_LEN(here->e_name_len);+		src = (char *) here + EXT3_XATTR_LEN(here->e_name_len);+		size = (char *) last - src;+		if ((char *) here + size > end)+			printk("ALERT at %s:%d: 0x%p + %d > 0x%p\n",+					__FILE__, __LINE__, here, size, end);+		memmove(here, src, size);+		last = (struct ext3_xattr_entry *) ((char *) last - border);+		*((__u32 *) last) = 0;+	}+	+	if (value) {+		int offs = min_offs - value_len;+		/* use last to create new entry */+		last->e_name_len = strlen(name);+		last->e_name_index = name_index;+		last->e_value_offs = cpu_to_le16(offs);+		last->e_value_size = cpu_to_le32(value_len);+		last->e_hash = last->e_value_block = 0;+		memset(last->e_name, 0, esize);+		memcpy(last->e_name, name, last->e_name_len);+		if (start + offs + value_len > end)+			printk("ALERT at %s:%d: 0x%p + %d + %zd > 0x%p\n",+			       __FILE__, __LINE__, start, offs,+			       value_len, end);+		memcpy(start + offs, value, value_len);+		last = EXT3_XATTR_NEXT(last);+		*((__u32 *) last) = 0;+	}+	+	ext3_mark_iloc_dirty(handle, inode, &iloc);+	brelse(bh);++	return 0;+}++/*  * ext3_xattr_set_handle()  *  * Create, replace or remove an extended attribute for this inode. Buffer@@ -470,6 +959,104 @@  */ int ext3_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,+		const char *name, const void *value, size_t value_len,+		int flags)+{+	struct ext3_xattr_entry entry;+	int err, where = 0, found = 0, total;+	int free1 = -1, free2 = -1;+	int name_len;+	+	ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",+		  name_index, name, value, (long)value_len);++	if (IS_RDONLY(inode))+		return -EROFS;+	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))+		return -EPERM;+	if (value == NULL)+		value_len = 0;+	if (name == NULL)+		return -EINVAL;+	name_len = strlen(name);+	if (name_len > 255 || value_len > inode->i_sb->s_blocksize)+		return -ERANGE;+	down_write(&EXT3_I(inode)->xattr_sem);++	/* try to find attribute in inode body */+	err = ext3_xattr_ibody_find(inode, name_index, name, &entry, &free1);+	if (err == 0) {+		/* found EA in inode */+		found = 1;+		where = 0;+	} else if (err == -ENOENT) {+		/* there is no such attribute in inode body */+		/* try to find attribute in dedicated block */+		err = ext3_xattr_block_find(inode, name_index, name,+						&entry, &free2);+		if (err != 0 && err != -ENOENT) {+			/* not found EA in block */+			goto finish;	+		} else if (err == 0) {+			/* found EA in block */+			where = 1;+			found = 1;+		}+	} else+		goto finish;++	/* check flags: may replace? may create ? */+	if (found && (flags & XATTR_CREATE)) {+		err = -EEXIST;+		goto finish;+	} else if (!found && (flags & XATTR_REPLACE)) {+		err = -ENODATA;+		goto finish;+	}++	/* check if we have enough space to store attribute */+	total = EXT3_XATTR_LEN(strlen(name)) + value_len;+	if (free1 >= 0 && total > free1 && free2 >= 0 && total > free2) {+		/* have no enough space */+		err = -ENOSPC;+		goto finish;+	}+	+	/* time to remove attribute */+	if (found) {+		if (where == 0) {+			/* EA is stored in inode body */+			ext3_xattr_ibody_set(handle, inode, name_index, name,+					NULL, 0, flags);+		} else {+			/* EA is stored in separated block */+			ext3_xattr_block_set(handle, inode, name_index, name,+					NULL, 0, flags);+		}+	}++	/* try to store EA in inode body */+	err = ext3_xattr_ibody_set(handle, inode, name_index, name,+				value, value_len, flags);+	if (err) {+		/* can't store EA in inode body */+		/* try to store in block */+		err = ext3_xattr_block_set(handle, inode, name_index,+					name, value, value_len, flags);	+	}++finish:	+	up_write(&EXT3_I(inode)->xattr_sem);+	return err;+}++/*+ * ext3_xattr_block_set()+ *+ * this routine add/remove/replace attribute in EA block+ */+int+ext3_xattr_block_set(handle_t *handle, struct inode *inode, int name_index, 		      const char *name, const void *value, size_t value_len, 		      int flags) {@@ -492,22 +1078,7 @@ 	 *             towards the end of the block). 	 * end -- Points right after the block pointed to by header. 	 */--	ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",-		  name_index, name, value, (long)value_len);--	if (IS_RDONLY(inode))-		return -EROFS;-	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))-		return -EPERM;-	if (value == NULL)-		value_len = 0;-	if (name == NULL)-		return -EINVAL; 	name_len = strlen(name);-	if (name_len > 255 || value_len > sb->s_blocksize)-		return -ERANGE;-	down_write(&EXT3_I(inode)->xattr_sem); 	if (EXT3_I(inode)->i_file_acl) { 		/* The inode already has an extended attribute block. */ 		bh = sb_bread(sb, EXT3_I(inode)->i_file_acl);@@ -733,7 +1304,6 @@ 	brelse(bh); 	if (!(bh && header == HDR(bh))) 		kfree(header);-	up_write(&EXT3_I(inode)->xattr_sem);  	return error; }Index: linux-2.6.0/fs/ext3/xattr.h===================================================================--- linux-2.6.0.orig/fs/ext3/xattr.h	2003-06-24 18:04:43.000000000 +0400+++ linux-2.6.0/fs/ext3/xattr.h	2004-01-14 18:54:12.000000000 +0300@@ -77,7 +77,8 @@ extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t); extern int ext3_xattr_list(struct inode *, char *, size_t); extern int ext3_xattr_set(struct inode *, int, const char *, const void *, size_t, int);-extern int ext3_xattr_set_handle(handle_t *, struct inode *, int, const char *, const void *, size_t, int);+extern int ext3_xattr_set_handle(handle_t *, struct inode *, int, const char *,const void *,size_t,int);+extern int ext3_xattr_block_set(handle_t *, struct inode *, int, const char *,const void *,size_t,int);  extern void ext3_xattr_delete_inode(handle_t *, struct inode *); extern void ext3_xattr_put_super(struct super_block *);Index: linux-2.6.0/include/linux/ext3_fs.h===================================================================--- linux-2.6.0.orig/include/linux/ext3_fs.h	2004-01-14 18:54:11.000000000 +0300+++ linux-2.6.0/include/linux/ext3_fs.h	2004-01-14 18:54:12.000000000 +0300@@ -265,6 +265,8 @@ 			__u32	m_i_reserved2[2]; 		} masix2; 	} osd2;				/* OS dependent 2 */+	__u16	i_extra_isize;+	__u16	i_pad1; };  #define i_size_high	i_dir_acl@@ -721,6 +723,7 @@ extern int ext3_forget(handle_t *, int, struct inode *, struct buffer_head *, int); extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *); extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *);+int ext3_get_inode_loc(struct inode *inode, struct ext3_iloc *iloc, int in_mem);  extern void ext3_read_inode (struct inode *); extern void ext3_write_inode (struct inode *, int);Index: linux-2.6.0/include/linux/ext3_fs_i.h===================================================================--- linux-2.6.0.orig/include/linux/ext3_fs_i.h	2003-12-30 08:32:44.000000000 +0300+++ linux-2.6.0/include/linux/ext3_fs_i.h	2004-01-14 18:54:12.000000000 +0300@@ -96,6 +96,9 @@ 	 */ 	loff_t	i_disksize; +	/* on-disk additional length */+	__u16 i_extra_isize;+ 	/* 	 * truncate_sem is for serialising ext3_truncate() against 	 * ext3_getblock().  In the 2.4 ext2 design, great chunks of inode's%diffstat fs/ext3/ialloc.c          |    5  fs/ext3/inode.c           |   10  fs/ext3/xattr.c           |  634 +++++++++++++++++++++++++++++++++++++++++++--- fs/ext3/xattr.h           |    3  include/linux/ext3_fs.h   |    2  include/linux/ext3_fs_i.h |    3  6 files changed, 623 insertions(+), 34 deletions(-)

⌨️ 快捷键说明

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