* [PATCH v2 4/4] hfsplus: add support of manipulation by attributes file
@ 2012-09-23 14:49 Vyacheslav Dubeyko
2012-10-01 11:24 ` Hin-Tak Leung
0 siblings, 1 reply; 3+ messages in thread
From: Vyacheslav Dubeyko @ 2012-09-23 14:49 UTC (permalink / raw)
To: linux-fsdevel, Andrew Morton, Christoph Hellwig, Al Viro; +Cc: Hin-Tak Leung
Hi,
This patch adds support of manipulation by attributes file.
With the best regards,
Vyacheslav Dubeyko.
---
From: Vyacheslav Dubeyko <slava@dubeyko.com>
Subject: [PATCH v2 4/4] hfsplus: add support of manipulation by attributes file
This patch adds support of manipulation by attributes file.
Reported-by: Hin-Tak Leung <htl10@users.sourceforge.net>
Signed-off-by: Vyacheslav Dubeyko <slava@dubeyko.com>
---
fs/hfsplus/bfind.c | 79 ++++++++++++++++++++++++++++++++++++++++-------
fs/hfsplus/bnode.c | 6 ++--
fs/hfsplus/brec.c | 23 ++++++++------
fs/hfsplus/btree.c | 8 +++++
fs/hfsplus/catalog.c | 36 ++++++++++++---------
fs/hfsplus/dir.c | 6 +++-
fs/hfsplus/extents.c | 4 +--
fs/hfsplus/hfsplus_fs.h | 41 +++++++++++++++++++++---
fs/hfsplus/inode.c | 13 ++++++++
fs/hfsplus/super.c | 36 +++++++++++++++++++--
fs/hfsplus/unicode.c | 7 +++--
11 files changed, 210 insertions(+), 49 deletions(-)
mode change 100644 => 100755 fs/hfsplus/bfind.c
mode change 100644 => 100755 fs/hfsplus/bnode.c
mode change 100644 => 100755 fs/hfsplus/brec.c
mode change 100644 => 100755 fs/hfsplus/btree.c
mode change 100644 => 100755 fs/hfsplus/catalog.c
mode change 100644 => 100755 fs/hfsplus/dir.c
mode change 100644 => 100755 fs/hfsplus/extents.c
mode change 100644 => 100755 fs/hfsplus/hfsplus_fs.h
mode change 100644 => 100755 fs/hfsplus/inode.c
mode change 100644 => 100755 fs/hfsplus/super.c
mode change 100644 => 100755 fs/hfsplus/unicode.c
diff --git a/fs/hfsplus/bfind.c b/fs/hfsplus/bfind.c
old mode 100644
new mode 100755
index 5d799c1..55baffa
--- a/fs/hfsplus/bfind.c
+++ b/fs/hfsplus/bfind.c
@@ -38,15 +38,73 @@ void hfs_find_exit(struct hfs_find_data *fd)
fd->tree = NULL;
}
-/* Find the record in bnode that best matches key (not greater than...)*/
-int __hfs_brec_find(struct hfs_bnode *bnode, struct hfs_find_data *fd)
+int hfs_find_1st_rec_by_cnid(struct hfs_bnode *bnode,
+ struct hfs_find_data *fd,
+ int *begin,
+ int *end,
+ int *cur_rec)
+{
+ __be32 cur_cnid, search_cnid;
+
+ if (bnode->tree->cnid == HFSPLUS_EXT_CNID) {
+ cur_cnid = fd->key->ext.cnid;
+ search_cnid = fd->search_key->ext.cnid;
+ } else if (bnode->tree->cnid == HFSPLUS_CAT_CNID) {
+ cur_cnid = fd->key->cat.parent;
+ search_cnid = fd->search_key->cat.parent;
+ } else if (bnode->tree->cnid == HFSPLUS_ATTR_CNID) {
+ cur_cnid = fd->key->attr.cnid;
+ search_cnid = fd->search_key->attr.cnid;
+ } else
+ BUG();
+
+ if (cur_cnid == search_cnid) {
+ (*end) = (*cur_rec);
+ if ((*begin) == (*end))
+ return 1;
+ } else {
+ if (be32_to_cpu(cur_cnid) < be32_to_cpu(search_cnid))
+ (*begin) = (*cur_rec) + 1;
+ else
+ (*end) = (*cur_rec) - 1;
+ }
+
+ return 0;
+}
+
+int hfs_find_rec_by_key(struct hfs_bnode *bnode,
+ struct hfs_find_data *fd,
+ int *begin,
+ int *end,
+ int *cur_rec)
{
int cmpval;
+
+ cmpval = bnode->tree->keycmp(fd->key, fd->search_key);
+ if (!cmpval) {
+ (*end) = (*cur_rec);
+ return 1;
+ }
+ if (cmpval < 0)
+ (*begin) = (*cur_rec) + 1;
+ else
+ *(end) = (*cur_rec) - 1;
+
+ return 0;
+}
+
+/* Find the record in bnode that best matches key (not greater than...)*/
+int __hfs_brec_find(struct hfs_bnode *bnode, struct hfs_find_data *fd,
+ search_strategy_t rec_found)
+{
u16 off, len, keylen;
int rec;
int b, e;
int res;
+ if (!rec_found)
+ BUG();
+
b = 0;
e = bnode->num_recs - 1;
res = -ENOENT;
@@ -59,17 +117,12 @@ int __hfs_brec_find(struct hfs_bnode *bnode, struct hfs_find_data *fd)
goto fail;
}
hfs_bnode_read(bnode, fd->key, off, keylen);
- cmpval = bnode->tree->keycmp(fd->key, fd->search_key);
- if (!cmpval) {
- e = rec;
+ if (rec_found(bnode, fd, &b, &e, &rec)) {
res = 0;
goto done;
}
- if (cmpval < 0)
- b = rec + 1;
- else
- e = rec - 1;
} while (b <= e);
+
if (rec != e && e >= 0) {
len = hfs_brec_lenoff(bnode, e, &off);
keylen = hfs_brec_keylen(bnode, e);
@@ -79,19 +132,21 @@ int __hfs_brec_find(struct hfs_bnode *bnode, struct hfs_find_data *fd)
}
hfs_bnode_read(bnode, fd->key, off, keylen);
}
+
done:
fd->record = e;
fd->keyoffset = off;
fd->keylength = keylen;
fd->entryoffset = off + keylen;
fd->entrylength = len - keylen;
+
fail:
return res;
}
/* Traverse a B*Tree from the root to a leaf finding best fit to key */
/* Return allocated copy of node found, set recnum to best record */
-int hfs_brec_find(struct hfs_find_data *fd)
+int hfs_brec_find(struct hfs_find_data *fd, search_strategy_t do_key_compare)
{
struct hfs_btree *tree;
struct hfs_bnode *bnode;
@@ -122,7 +177,7 @@ int hfs_brec_find(struct hfs_find_data *fd)
goto invalid;
bnode->parent = parent;
- res = __hfs_brec_find(bnode, fd);
+ res = __hfs_brec_find(bnode, fd, do_key_compare);
if (!height)
break;
if (fd->record < 0)
@@ -149,7 +204,7 @@ int hfs_brec_read(struct hfs_find_data *fd, void *rec, int rec_len)
{
int res;
- res = hfs_brec_find(fd);
+ res = hfs_brec_find(fd, hfs_find_rec_by_key);
if (res)
return res;
if (fd->entrylength > rec_len)
diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c
old mode 100644
new mode 100755
index 1c42cc5..5c125ce
--- a/fs/hfsplus/bnode.c
+++ b/fs/hfsplus/bnode.c
@@ -62,7 +62,8 @@ void hfs_bnode_read_key(struct hfs_bnode *node, void *key, int off)
tree = node->tree;
if (node->type == HFS_NODE_LEAF ||
- tree->attributes & HFS_TREE_VARIDXKEYS)
+ tree->attributes & HFS_TREE_VARIDXKEYS ||
+ node->tree->cnid == HFSPLUS_ATTR_CNID)
key_len = hfs_bnode_read_u16(node, off) + 2;
else
key_len = tree->max_key_len + 2;
@@ -314,7 +315,8 @@ void hfs_bnode_dump(struct hfs_bnode *node)
if (i && node->type == HFS_NODE_INDEX) {
int tmp;
- if (node->tree->attributes & HFS_TREE_VARIDXKEYS)
+ if (node->tree->attributes & HFS_TREE_VARIDXKEYS ||
+ node->tree->cnid == HFSPLUS_ATTR_CNID)
tmp = hfs_bnode_read_u16(node, key_off) + 2;
else
tmp = node->tree->max_key_len + 2;
diff --git a/fs/hfsplus/brec.c b/fs/hfsplus/brec.c
old mode 100644
new mode 100755
index 2a734cf..298d4e4
--- a/fs/hfsplus/brec.c
+++ b/fs/hfsplus/brec.c
@@ -36,7 +36,8 @@ u16 hfs_brec_keylen(struct hfs_bnode *node, u16 rec)
return 0;
if ((node->type == HFS_NODE_INDEX) &&
- !(node->tree->attributes & HFS_TREE_VARIDXKEYS)) {
+ !(node->tree->attributes & HFS_TREE_VARIDXKEYS) &&
+ (node->tree->cnid != HFSPLUS_ATTR_CNID)) {
retval = node->tree->max_key_len + 2;
} else {
recoff = hfs_bnode_read_u16(node,
@@ -151,12 +152,13 @@ skip:
/* get index key */
hfs_bnode_read_key(new_node, fd->search_key, 14);
- __hfs_brec_find(fd->bnode, fd);
+ __hfs_brec_find(fd->bnode, fd, hfs_find_rec_by_key);
hfs_bnode_put(new_node);
new_node = NULL;
- if (tree->attributes & HFS_TREE_VARIDXKEYS)
+ if ((tree->attributes & HFS_TREE_VARIDXKEYS) ||
+ (tree->cnid == HFSPLUS_ATTR_CNID))
key_len = be16_to_cpu(fd->search_key->key_len) + 2;
else {
fd->search_key->key_len =
@@ -201,7 +203,7 @@ again:
hfs_bnode_put(node);
node = fd->bnode = parent;
- __hfs_brec_find(node, fd);
+ __hfs_brec_find(node, fd, hfs_find_rec_by_key);
goto again;
}
hfs_bnode_write_u16(node,
@@ -367,12 +369,13 @@ again:
parent = hfs_bnode_find(tree, node->parent);
if (IS_ERR(parent))
return PTR_ERR(parent);
- __hfs_brec_find(parent, fd);
+ __hfs_brec_find(parent, fd, hfs_find_rec_by_key);
hfs_bnode_dump(parent);
rec = fd->record;
/* size difference between old and new key */
- if (tree->attributes & HFS_TREE_VARIDXKEYS)
+ if ((tree->attributes & HFS_TREE_VARIDXKEYS) ||
+ (tree->cnid == HFSPLUS_ATTR_CNID))
newkeylen = hfs_bnode_read_u16(node, 14) + 2;
else
fd->keylength = newkeylen = tree->max_key_len + 2;
@@ -427,7 +430,7 @@ skip:
hfs_bnode_read_key(new_node, fd->search_key, 14);
cnid = cpu_to_be32(new_node->this);
- __hfs_brec_find(fd->bnode, fd);
+ __hfs_brec_find(fd->bnode, fd, hfs_find_rec_by_key);
hfs_brec_insert(fd, &cnid, sizeof(cnid));
hfs_bnode_put(fd->bnode);
hfs_bnode_put(new_node);
@@ -495,13 +498,15 @@ static int hfs_btree_inc_height(struct hfs_btree *tree)
/* insert old root idx into new root */
node->parent = tree->root;
if (node->type == HFS_NODE_LEAF ||
- tree->attributes & HFS_TREE_VARIDXKEYS)
+ tree->attributes & HFS_TREE_VARIDXKEYS ||
+ tree->cnid == HFSPLUS_ATTR_CNID)
key_size = hfs_bnode_read_u16(node, 14) + 2;
else
key_size = tree->max_key_len + 2;
hfs_bnode_copy(new_node, 14, node, 14, key_size);
- if (!(tree->attributes & HFS_TREE_VARIDXKEYS)) {
+ if (!(tree->attributes & HFS_TREE_VARIDXKEYS) &&
+ (tree->cnid != HFSPLUS_ATTR_CNID)) {
key_size = tree->max_key_len + 2;
hfs_bnode_write_u16(new_node, 14, tree->max_key_len);
}
diff --git a/fs/hfsplus/btree.c b/fs/hfsplus/btree.c
old mode 100644
new mode 100755
index 21023d9..44294af
--- a/fs/hfsplus/btree.c
+++ b/fs/hfsplus/btree.c
@@ -98,6 +98,14 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id)
set_bit(HFSPLUS_SB_CASEFOLD, &HFSPLUS_SB(sb)->flags);
}
break;
+ case HFSPLUS_ATTR_CNID:
+ if (tree->max_key_len != HFSPLUS_ATTR_KEYLEN - sizeof(u16)) {
+ printk(KERN_ERR "hfs: invalid attributes max_key_len %d\n",
+ tree->max_key_len);
+ goto fail_page;
+ }
+ tree->keycmp = hfsplus_attr_bin_cmp_key;
+ break;
default:
printk(KERN_ERR "hfs: unknown B*Tree requested\n");
goto fail_page;
diff --git a/fs/hfsplus/catalog.c b/fs/hfsplus/catalog.c
old mode 100644
new mode 100755
index ec2a9c2..c285c8d
--- a/fs/hfsplus/catalog.c
+++ b/fs/hfsplus/catalog.c
@@ -45,7 +45,8 @@ void hfsplus_cat_build_key(struct super_block *sb, hfsplus_btree_key *key,
key->cat.parent = cpu_to_be32(parent);
if (str) {
- hfsplus_asc2uni(sb, &key->cat.name, str->name, str->len);
+ hfsplus_asc2uni(sb, &key->cat.name, HFSPLUS_MAX_STRLEN,
+ str->name, str->len);
len = be16_to_cpu(key->cat.name.length);
} else {
key->cat.name.length = 0;
@@ -167,7 +168,8 @@ static int hfsplus_fill_cat_thread(struct super_block *sb,
entry->type = cpu_to_be16(type);
entry->thread.reserved = 0;
entry->thread.parentID = cpu_to_be32(parentid);
- hfsplus_asc2uni(sb, &entry->thread.nodeName, str->name, str->len);
+ hfsplus_asc2uni(sb, &entry->thread.nodeName, HFSPLUS_MAX_STRLEN,
+ str->name, str->len);
return 10 + be16_to_cpu(entry->thread.nodeName.length) * 2;
}
@@ -198,7 +200,7 @@ int hfsplus_find_cat(struct super_block *sb, u32 cnid,
hfsplus_cat_build_key_uni(fd->search_key,
be32_to_cpu(tmp.thread.parentID),
&tmp.thread.nodeName);
- return hfs_brec_find(fd);
+ return hfs_brec_find(fd, hfs_find_rec_by_key);
}
int hfsplus_create_cat(u32 cnid, struct inode *dir,
@@ -221,7 +223,7 @@ int hfsplus_create_cat(u32 cnid, struct inode *dir,
S_ISDIR(inode->i_mode) ?
HFSPLUS_FOLDER_THREAD : HFSPLUS_FILE_THREAD,
dir->i_ino, str);
- err = hfs_brec_find(&fd);
+ err = hfs_brec_find(&fd, hfs_find_rec_by_key);
if (err != -ENOENT) {
if (!err)
err = -EEXIST;
@@ -233,7 +235,7 @@ int hfsplus_create_cat(u32 cnid, struct inode *dir,
hfsplus_cat_build_key(sb, fd.search_key, dir->i_ino, str);
entry_size = hfsplus_cat_build_record(&entry, cnid, inode);
- err = hfs_brec_find(&fd);
+ err = hfs_brec_find(&fd, hfs_find_rec_by_key);
if (err != -ENOENT) {
/* panic? */
if (!err)
@@ -253,7 +255,7 @@ int hfsplus_create_cat(u32 cnid, struct inode *dir,
err1:
hfsplus_cat_build_key(sb, fd.search_key, cnid, NULL);
- if (!hfs_brec_find(&fd))
+ if (!hfs_brec_find(&fd, hfs_find_rec_by_key))
hfs_brec_remove(&fd);
err2:
hfs_find_exit(&fd);
@@ -279,7 +281,7 @@ int hfsplus_delete_cat(u32 cnid, struct inode *dir, struct qstr *str)
int len;
hfsplus_cat_build_key(sb, fd.search_key, cnid, NULL);
- err = hfs_brec_find(&fd);
+ err = hfs_brec_find(&fd, hfs_find_rec_by_key);
if (err)
goto out;
@@ -296,7 +298,7 @@ int hfsplus_delete_cat(u32 cnid, struct inode *dir, struct qstr *str)
} else
hfsplus_cat_build_key(sb, fd.search_key, dir->i_ino, str);
- err = hfs_brec_find(&fd);
+ err = hfs_brec_find(&fd, hfs_find_rec_by_key);
if (err)
goto out;
@@ -326,7 +328,7 @@ int hfsplus_delete_cat(u32 cnid, struct inode *dir, struct qstr *str)
goto out;
hfsplus_cat_build_key(sb, fd.search_key, cnid, NULL);
- err = hfs_brec_find(&fd);
+ err = hfs_brec_find(&fd, hfs_find_rec_by_key);
if (err)
goto out;
@@ -337,6 +339,12 @@ int hfsplus_delete_cat(u32 cnid, struct inode *dir, struct qstr *str)
dir->i_size--;
dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
hfsplus_mark_inode_dirty(dir, HFSPLUS_I_CAT_DIRTY);
+
+ if (type == HFSPLUS_FILE || type == HFSPLUS_FOLDER) {
+ if (HFSPLUS_SB(sb)->attr_tree)
+ hfsplus_delete_all_attrs(dir, cnid);
+ }
+
out:
hfs_find_exit(&fd);
@@ -363,7 +371,7 @@ int hfsplus_rename_cat(u32 cnid,
/* find the old dir entry and read the data */
hfsplus_cat_build_key(sb, src_fd.search_key, src_dir->i_ino, src_name);
- err = hfs_brec_find(&src_fd);
+ err = hfs_brec_find(&src_fd, hfs_find_rec_by_key);
if (err)
goto out;
if (src_fd.entrylength > sizeof(entry) || src_fd.entrylength < 0) {
@@ -376,7 +384,7 @@ int hfsplus_rename_cat(u32 cnid,
/* create new dir entry with the data from the old entry */
hfsplus_cat_build_key(sb, dst_fd.search_key, dst_dir->i_ino, dst_name);
- err = hfs_brec_find(&dst_fd);
+ err = hfs_brec_find(&dst_fd, hfs_find_rec_by_key);
if (err != -ENOENT) {
if (!err)
err = -EEXIST;
@@ -391,7 +399,7 @@ int hfsplus_rename_cat(u32 cnid,
/* finally remove the old entry */
hfsplus_cat_build_key(sb, src_fd.search_key, src_dir->i_ino, src_name);
- err = hfs_brec_find(&src_fd);
+ err = hfs_brec_find(&src_fd, hfs_find_rec_by_key);
if (err)
goto out;
err = hfs_brec_remove(&src_fd);
@@ -402,7 +410,7 @@ int hfsplus_rename_cat(u32 cnid,
/* remove old thread entry */
hfsplus_cat_build_key(sb, src_fd.search_key, cnid, NULL);
- err = hfs_brec_find(&src_fd);
+ err = hfs_brec_find(&src_fd, hfs_find_rec_by_key);
if (err)
goto out;
type = hfs_bnode_read_u16(src_fd.bnode, src_fd.entryoffset);
@@ -414,7 +422,7 @@ int hfsplus_rename_cat(u32 cnid,
hfsplus_cat_build_key(sb, dst_fd.search_key, cnid, NULL);
entry_size = hfsplus_fill_cat_thread(sb, &entry, type,
dst_dir->i_ino, dst_name);
- err = hfs_brec_find(&dst_fd);
+ err = hfs_brec_find(&dst_fd, hfs_find_rec_by_key);
if (err != -ENOENT) {
if (!err)
err = -EEXIST;
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c
old mode 100644
new mode 100755
index 6b9f921..40ceeab
--- a/fs/hfsplus/dir.c
+++ b/fs/hfsplus/dir.c
@@ -138,7 +138,7 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir)
if (err)
return err;
hfsplus_cat_build_key(sb, fd.search_key, inode->i_ino, NULL);
- err = hfs_brec_find(&fd);
+ err = hfs_brec_find(&fd, hfs_find_rec_by_key);
if (err)
goto out;
@@ -508,6 +508,10 @@ const struct inode_operations hfsplus_dir_inode_operations = {
.symlink = hfsplus_symlink,
.mknod = hfsplus_mknod,
.rename = hfsplus_rename,
+ .setxattr = hfsplus_setxattr,
+ .getxattr = hfsplus_getxattr,
+ .listxattr = hfsplus_listxattr,
+ .removexattr = hfsplus_removexattr,
};
const struct file_operations hfsplus_dir_operations = {
diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c
old mode 100644
new mode 100755
index 5849e3e..87e59e9
--- a/fs/hfsplus/extents.c
+++ b/fs/hfsplus/extents.c
@@ -95,7 +95,7 @@ static void __hfsplus_ext_write_extent(struct inode *inode,
HFSPLUS_IS_RSRC(inode) ?
HFSPLUS_TYPE_RSRC : HFSPLUS_TYPE_DATA);
- res = hfs_brec_find(fd);
+ res = hfs_brec_find(fd, hfs_find_rec_by_key);
if (hip->extent_state & HFSPLUS_EXT_NEW) {
if (res != -ENOENT)
return;
@@ -154,7 +154,7 @@ static inline int __hfsplus_ext_read_extent(struct hfs_find_data *fd,
hfsplus_ext_build_key(fd->search_key, cnid, block, type);
fd->key->ext.cnid = 0;
- res = hfs_brec_find(fd);
+ res = hfs_brec_find(fd, hfs_find_rec_by_key);
if (res && res != -ENOENT)
return res;
if (fd->key->ext.cnid != fd->search_key->ext.cnid ||
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
old mode 100644
new mode 100755
index 558dbb4..03ed580
--- a/fs/hfsplus/hfsplus_fs.h
+++ b/fs/hfsplus/hfsplus_fs.h
@@ -23,6 +23,7 @@
#define DBG_SUPER 0x00000010
#define DBG_EXTENT 0x00000020
#define DBG_BITMAP 0x00000040
+#define DBG_ATTR_MOD 0x00000080
#if 0
#define DBG_MASK (DBG_EXTENT|DBG_INODE|DBG_BNODE_MOD)
@@ -223,6 +224,7 @@ struct hfsplus_inode_info {
#define HFSPLUS_I_CAT_DIRTY 1 /* has changes in the catalog tree */
#define HFSPLUS_I_EXT_DIRTY 2 /* has changes in the extent tree */
#define HFSPLUS_I_ALLOC_DIRTY 3 /* has changes in the allocation file */
+#define HFSPLUS_I_ATTR_DIRTY 4 /* has changes in the attributes tree */
#define HFSPLUS_IS_RSRC(inode) \
test_bit(HFSPLUS_I_RSRC, &HFSPLUS_I(inode)->flags)
@@ -302,7 +304,7 @@ static inline unsigned short hfsplus_min_io_size(struct super_block *sb)
#define hfs_brec_remove hfsplus_brec_remove
#define hfs_find_init hfsplus_find_init
#define hfs_find_exit hfsplus_find_exit
-#define __hfs_brec_find __hplusfs_brec_find
+#define __hfs_brec_find __hfsplus_brec_find
#define hfs_brec_find hfsplus_brec_find
#define hfs_brec_read hfsplus_brec_read
#define hfs_brec_goto hfsplus_brec_goto
@@ -324,10 +326,33 @@ static inline unsigned short hfsplus_min_io_size(struct super_block *sb)
*/
#define HFSPLUS_IOC_BLESS _IO('h', 0x80)
+typedef int (*search_strategy_t)(struct hfs_bnode *,
+ struct hfs_find_data *,
+ int *, int *, int *);
+
/*
* Functions in any *.c used in other files
*/
+/* attributes.c */
+int hfsplus_create_attr_tree_cache(void);
+void hfsplus_destroy_attr_tree_cache(void);
+hfsplus_attr_entry *hfsplus_alloc_attr_entry(void);
+void hfsplus_destroy_attr_entry(hfsplus_attr_entry *entry_p);
+int hfsplus_attr_bin_cmp_key(const hfsplus_btree_key *,
+ const hfsplus_btree_key *);
+int hfsplus_attr_build_key(struct super_block *, hfsplus_btree_key *,
+ u32, const char *);
+void hfsplus_attr_build_key_uni(hfsplus_btree_key *key,
+ u32 cnid,
+ struct hfsplus_attr_unistr *name);
+int hfsplus_find_attr(struct super_block *, u32,
+ const char *, struct hfs_find_data *);
+int hfsplus_attr_exists(struct inode *inode, const char *name);
+int hfsplus_create_attr(struct inode *, const char *, const void *, size_t);
+int hfsplus_delete_attr(struct inode *, const char *);
+int hfsplus_delete_all_attrs(struct inode *dir, u32 cnid);
+
/* bitmap.c */
int hfsplus_block_allocate(struct super_block *, u32, u32, u32 *);
int hfsplus_block_free(struct super_block *, u32, u32);
@@ -369,8 +394,15 @@ int hfs_brec_remove(struct hfs_find_data *);
/* bfind.c */
int hfs_find_init(struct hfs_btree *, struct hfs_find_data *);
void hfs_find_exit(struct hfs_find_data *);
-int __hfs_brec_find(struct hfs_bnode *, struct hfs_find_data *);
-int hfs_brec_find(struct hfs_find_data *);
+int hfs_find_1st_rec_by_cnid(struct hfs_bnode *,
+ struct hfs_find_data *,
+ int *, int *, int *);
+int hfs_find_rec_by_key(struct hfs_bnode *,
+ struct hfs_find_data *,
+ int *, int *, int *);
+int __hfs_brec_find(struct hfs_bnode *, struct hfs_find_data *,
+ search_strategy_t);
+int hfs_brec_find(struct hfs_find_data *, search_strategy_t);
int hfs_brec_read(struct hfs_find_data *, void *, int);
int hfs_brec_goto(struct hfs_find_data *, int);
@@ -422,6 +454,7 @@ int hfsplus_setxattr(struct dentry *dentry, const char *name,
ssize_t hfsplus_getxattr(struct dentry *dentry, const char *name,
void *value, size_t size);
ssize_t hfsplus_listxattr(struct dentry *dentry, char *buffer, size_t size);
+int hfsplus_removexattr(struct dentry *dentry, const char *name);
/* options.c */
int hfsplus_parse_options(char *, struct hfsplus_sb_info *);
@@ -446,7 +479,7 @@ int hfsplus_strcmp(const struct hfsplus_unistr *,
int hfsplus_uni2asc(struct super_block *,
const struct hfsplus_unistr *, char *, int *);
int hfsplus_asc2uni(struct super_block *,
- struct hfsplus_unistr *, const char *, int);
+ struct hfsplus_unistr *, int, const char *, int);
int hfsplus_hash_dentry(const struct dentry *dentry,
const struct inode *inode, struct qstr *str);
int hfsplus_compare_dentry(const struct dentry *parent,
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
old mode 100644
new mode 100755
index 3d8b4a6..98a6210
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -342,6 +342,18 @@ int hfsplus_file_fsync(struct file *file, loff_t start, loff_t end,
error = error2;
}
+ if (test_and_clear_bit(HFSPLUS_I_ATTR_DIRTY, &hip->flags)) {
+ if (sbi->attr_tree) {
+ error2 =
+ filemap_write_and_wait(
+ sbi->attr_tree->inode->i_mapping);
+ if (!error)
+ error = error2;
+ } else {
+ printk(KERN_ERR "hfs: sync non-existent attributes tree\n");
+ }
+ }
+
if (test_and_clear_bit(HFSPLUS_I_ALLOC_DIRTY, &hip->flags)) {
error2 = filemap_write_and_wait(sbi->alloc_file->i_mapping);
if (!error)
@@ -363,6 +375,7 @@ static const struct inode_operations hfsplus_file_inode_operations = {
.setxattr = hfsplus_setxattr,
.getxattr = hfsplus_getxattr,
.listxattr = hfsplus_listxattr,
+ .removexattr = hfsplus_removexattr,
};
static const struct file_operations hfsplus_file_operations = {
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
old mode 100644
new mode 100755
index fdafb2d..5a7c91e
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -118,6 +118,7 @@ static int hfsplus_system_write_inode(struct inode *inode)
case HFSPLUS_ATTR_CNID:
fork = &vhdr->attr_file;
tree = sbi->attr_tree;
+ break;
default:
return -EIO;
}
@@ -185,6 +186,12 @@ static int hfsplus_sync_fs(struct super_block *sb, int wait)
error2 = filemap_write_and_wait(sbi->ext_tree->inode->i_mapping);
if (!error)
error = error2;
+ if (sbi->attr_tree) {
+ error2 =
+ filemap_write_and_wait(sbi->attr_tree->inode->i_mapping);
+ if (!error)
+ error = error2;
+ }
error2 = filemap_write_and_wait(sbi->alloc_file->i_mapping);
if (!error)
error = error2;
@@ -272,6 +279,7 @@ static void hfsplus_put_super(struct super_block *sb)
hfsplus_sync_fs(sb, 1);
}
+ hfs_btree_close(sbi->attr_tree);
hfs_btree_close(sbi->cat_tree);
hfs_btree_close(sbi->ext_tree);
iput(sbi->alloc_file);
@@ -468,12 +476,19 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
printk(KERN_ERR "hfs: failed to load catalog file\n");
goto out_close_ext_tree;
}
+ if (vhdr->attr_file.total_blocks != 0) {
+ sbi->attr_tree = hfs_btree_open(sb, HFSPLUS_ATTR_CNID);
+ if (!sbi->attr_tree) {
+ printk(KERN_ERR "hfs: failed to load attributes file\n");
+ goto out_close_cat_tree;
+ }
+ }
inode = hfsplus_iget(sb, HFSPLUS_ALLOC_CNID);
if (IS_ERR(inode)) {
printk(KERN_ERR "hfs: failed to load allocation file\n");
err = PTR_ERR(inode);
- goto out_close_cat_tree;
+ goto out_close_attr_tree;
}
sbi->alloc_file = inode;
@@ -553,6 +568,8 @@ out_put_root:
sb->s_root = NULL;
out_put_alloc_file:
iput(sbi->alloc_file);
+out_close_attr_tree:
+ hfs_btree_close(sbi->attr_tree);
out_close_cat_tree:
hfs_btree_close(sbi->cat_tree);
out_close_ext_tree:
@@ -626,15 +643,30 @@ static int __init init_hfsplus_fs(void)
hfsplus_init_once);
if (!hfsplus_inode_cachep)
return -ENOMEM;
+
+ err = hfsplus_create_attr_tree_cache();
+ if (err)
+ goto destroy_inode_cache;
+
err = register_filesystem(&hfsplus_fs_type);
if (err)
- kmem_cache_destroy(hfsplus_inode_cachep);
+ goto destroy_attr_tree_cache;
+
+ return 0;
+
+destroy_attr_tree_cache:
+ hfsplus_destroy_attr_tree_cache();
+
+destroy_inode_cache:
+ kmem_cache_destroy(hfsplus_inode_cachep);
+
return err;
}
static void __exit exit_hfsplus_fs(void)
{
unregister_filesystem(&hfsplus_fs_type);
+ hfsplus_destroy_attr_tree_cache();
kmem_cache_destroy(hfsplus_inode_cachep);
}
diff --git a/fs/hfsplus/unicode.c b/fs/hfsplus/unicode.c
old mode 100644
new mode 100755
index a32998f..2c2e47d
--- a/fs/hfsplus/unicode.c
+++ b/fs/hfsplus/unicode.c
@@ -295,7 +295,8 @@ static inline u16 *decompose_unichar(wchar_t uc, int *size)
return hfsplus_decompose_table + (off / 4);
}
-int hfsplus_asc2uni(struct super_block *sb, struct hfsplus_unistr *ustr,
+int hfsplus_asc2uni(struct super_block *sb,
+ struct hfsplus_unistr *ustr, int max_unistr_len,
const char *astr, int len)
{
int size, dsize, decompose;
@@ -303,7 +304,7 @@ int hfsplus_asc2uni(struct super_block *sb, struct hfsplus_unistr *ustr,
wchar_t c;
decompose = !test_bit(HFSPLUS_SB_NODECOMPOSE, &HFSPLUS_SB(sb)->flags);
- while (outlen < HFSPLUS_MAX_STRLEN && len > 0) {
+ while (outlen < max_unistr_len && len > 0) {
size = asc2unichar(sb, astr, len, &c);
if (decompose)
@@ -311,7 +312,7 @@ int hfsplus_asc2uni(struct super_block *sb, struct hfsplus_unistr *ustr,
else
dstr = NULL;
if (dstr) {
- if (outlen + dsize > HFSPLUS_MAX_STRLEN)
+ if (outlen + dsize > max_unistr_len)
break;
do {
ustr->unicode[outlen++] = cpu_to_be16(*dstr++);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v2 4/4] hfsplus: add support of manipulation by attributes file
2012-09-23 14:49 [PATCH v2 4/4] hfsplus: add support of manipulation by attributes file Vyacheslav Dubeyko
@ 2012-10-01 11:24 ` Hin-Tak Leung
2012-10-01 11:52 ` Vyacheslav Dubeyko
0 siblings, 1 reply; 3+ messages in thread
From: Hin-Tak Leung @ 2012-10-01 11:24 UTC (permalink / raw)
To: linux-fsdevel, Andrew Morton, Christoph Hellwig, Al Viro,
Vyacheslav Dubeyko
--- On Sun, 23/9/12, Vyacheslav Dubeyko <slava@dubeyko.com> wrote:
> Hi,
>
> This patch adds support of manipulation by attributes file.
>
> With the best regards,
> Vyacheslav Dubeyko.
> ---
> From: Vyacheslav Dubeyko <slava@dubeyko.com>
> Subject: [PATCH v2 4/4] hfsplus: add support of manipulation
> by attributes file
>
> This patch adds support of manipulation by attributes file.
>
> Reported-by: Hin-Tak Leung <htl10@users.sourceforge.net>
> Signed-off-by: Vyacheslav Dubeyko <slava@dubeyko.com>
Tested-by: Hin-Tak Leung <htl10@users.sourceforge.net>
Tried these 4 patches -together with the 5th which acted on code reviews and feedback. Works okay and fixed the two minor problems I had work v 1 (dubious warnings and interactions with selinux's use of extended atttributes).
There is a small problem though - this set of patches changes the file modes of some of the files, as seen below - just scroll further down... The other patches also touch the file modes where files are modified.
Hin-Tak
> ---
> fs/hfsplus/bfind.c
> | 79
> ++++++++++++++++++++++++++++++++++++++++-------
> fs/hfsplus/bnode.c | 6
> ++--
> fs/hfsplus/brec.c
> | 23 ++++++++------
> fs/hfsplus/btree.c | 8
> +++++
> fs/hfsplus/catalog.c | 36
> ++++++++++++---------
> fs/hfsplus/dir.c |
> 6 +++-
> fs/hfsplus/extents.c | 4 +--
> fs/hfsplus/hfsplus_fs.h | 41
> +++++++++++++++++++++---
> fs/hfsplus/inode.c
> | 13 ++++++++
> fs/hfsplus/super.c
> | 36 +++++++++++++++++++--
> fs/hfsplus/unicode.c | 7 +++--
> 11 files changed, 210 insertions(+), 49 deletions(-)
> mode change 100644 => 100755 fs/hfsplus/bfind.c
> mode change 100644 => 100755 fs/hfsplus/bnode.c
> mode change 100644 => 100755 fs/hfsplus/brec.c
> mode change 100644 => 100755 fs/hfsplus/btree.c
> mode change 100644 => 100755 fs/hfsplus/catalog.c
> mode change 100644 => 100755 fs/hfsplus/dir.c
> mode change 100644 => 100755 fs/hfsplus/extents.c
> mode change 100644 => 100755 fs/hfsplus/hfsplus_fs.h
> mode change 100644 => 100755 fs/hfsplus/inode.c
> mode change 100644 => 100755 fs/hfsplus/super.c
> mode change 100644 => 100755 fs/hfsplus/unicode.c
Here - the file modes should not be touched...
> diff --git a/fs/hfsplus/bfind.c b/fs/hfsplus/bfind.c
> old mode 100644
> new mode 100755
> index 5d799c1..55baffa
> --- a/fs/hfsplus/bfind.c
> +++ b/fs/hfsplus/bfind.c
> @@ -38,15 +38,73 @@ void hfs_find_exit(struct hfs_find_data
> *fd)
> fd->tree = NULL;
> }
>
> -/* Find the record in bnode that best matches key (not
> greater than...)*/
> -int __hfs_brec_find(struct hfs_bnode *bnode, struct
> hfs_find_data *fd)
> +int hfs_find_1st_rec_by_cnid(struct hfs_bnode *bnode,
> +
> struct hfs_find_data *fd,
> +
> int *begin,
> +
> int *end,
> +
> int *cur_rec)
> +{
> + __be32 cur_cnid, search_cnid;
> +
> + if (bnode->tree->cnid ==
> HFSPLUS_EXT_CNID) {
> + cur_cnid =
> fd->key->ext.cnid;
> + search_cnid =
> fd->search_key->ext.cnid;
> + } else if (bnode->tree->cnid ==
> HFSPLUS_CAT_CNID) {
> + cur_cnid =
> fd->key->cat.parent;
> + search_cnid =
> fd->search_key->cat.parent;
> + } else if (bnode->tree->cnid ==
> HFSPLUS_ATTR_CNID) {
> + cur_cnid =
> fd->key->attr.cnid;
> + search_cnid =
> fd->search_key->attr.cnid;
> + } else
> + BUG();
> +
> + if (cur_cnid == search_cnid) {
> + (*end) = (*cur_rec);
> + if ((*begin) ==
> (*end))
> +
> return 1;
> + } else {
> + if
> (be32_to_cpu(cur_cnid) < be32_to_cpu(search_cnid))
> +
> (*begin) = (*cur_rec) + 1;
> + else
> +
> (*end) = (*cur_rec) - 1;
> + }
> +
> + return 0;
> +}
> +
> +int hfs_find_rec_by_key(struct hfs_bnode *bnode,
> +
> struct hfs_find_data *fd,
> +
> int *begin,
> +
> int *end,
> +
> int *cur_rec)
> {
> int cmpval;
> +
> + cmpval =
> bnode->tree->keycmp(fd->key, fd->search_key);
> + if (!cmpval) {
> + (*end) = (*cur_rec);
> + return 1;
> + }
> + if (cmpval < 0)
> + (*begin) = (*cur_rec)
> + 1;
> + else
> + *(end) = (*cur_rec) -
> 1;
> +
> + return 0;
> +}
> +
> +/* Find the record in bnode that best matches key (not
> greater than...)*/
> +int __hfs_brec_find(struct hfs_bnode *bnode, struct
> hfs_find_data *fd,
> +
> search_strategy_t
> rec_found)
> +{
> u16 off, len, keylen;
> int rec;
> int b, e;
> int res;
>
> + if (!rec_found)
> + BUG();
> +
> b = 0;
> e = bnode->num_recs - 1;
> res = -ENOENT;
> @@ -59,17 +117,12 @@ int __hfs_brec_find(struct hfs_bnode
> *bnode, struct hfs_find_data *fd)
>
> goto fail;
> }
> hfs_bnode_read(bnode,
> fd->key, off, keylen);
> - cmpval =
> bnode->tree->keycmp(fd->key, fd->search_key);
> - if (!cmpval) {
> - e
> = rec;
> + if (rec_found(bnode,
> fd, &b, &e, &rec)) {
>
> res = 0;
>
> goto done;
> }
> - if (cmpval < 0)
> - b
> = rec + 1;
> - else
> - e
> = rec - 1;
> } while (b <= e);
> +
> if (rec != e && e >= 0) {
> len =
> hfs_brec_lenoff(bnode, e, &off);
> keylen =
> hfs_brec_keylen(bnode, e);
> @@ -79,19 +132,21 @@ int __hfs_brec_find(struct hfs_bnode
> *bnode, struct hfs_find_data *fd)
> }
> hfs_bnode_read(bnode,
> fd->key, off, keylen);
> }
> +
> done:
> fd->record = e;
> fd->keyoffset = off;
> fd->keylength = keylen;
> fd->entryoffset = off + keylen;
> fd->entrylength = len - keylen;
> +
> fail:
> return res;
> }
>
> /* Traverse a B*Tree from the root to a leaf finding best
> fit to key */
> /* Return allocated copy of node found, set recnum to best
> record */
> -int hfs_brec_find(struct hfs_find_data *fd)
> +int hfs_brec_find(struct hfs_find_data *fd,
> search_strategy_t do_key_compare)
> {
> struct hfs_btree *tree;
> struct hfs_bnode *bnode;
> @@ -122,7 +177,7 @@ int hfs_brec_find(struct hfs_find_data
> *fd)
>
> goto invalid;
> bnode->parent =
> parent;
>
> - res =
> __hfs_brec_find(bnode, fd);
> + res =
> __hfs_brec_find(bnode, fd, do_key_compare);
> if (!height)
>
> break;
> if (fd->record
> < 0)
> @@ -149,7 +204,7 @@ int hfs_brec_read(struct hfs_find_data
> *fd, void *rec, int rec_len)
> {
> int res;
>
> - res = hfs_brec_find(fd);
> + res = hfs_brec_find(fd,
> hfs_find_rec_by_key);
> if (res)
> return res;
> if (fd->entrylength > rec_len)
> diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c
> old mode 100644
> new mode 100755
> index 1c42cc5..5c125ce
> --- a/fs/hfsplus/bnode.c
> +++ b/fs/hfsplus/bnode.c
> @@ -62,7 +62,8 @@ void hfs_bnode_read_key(struct hfs_bnode
> *node, void *key, int off)
>
> tree = node->tree;
> if (node->type == HFS_NODE_LEAF ||
> - tree->attributes &
> HFS_TREE_VARIDXKEYS)
> + tree->attributes &
> HFS_TREE_VARIDXKEYS ||
> + node->tree->cnid ==
> HFSPLUS_ATTR_CNID)
> key_len =
> hfs_bnode_read_u16(node, off) + 2;
> else
> key_len =
> tree->max_key_len + 2;
> @@ -314,7 +315,8 @@ void hfs_bnode_dump(struct hfs_bnode
> *node)
> if (i &&
> node->type == HFS_NODE_INDEX) {
>
> int tmp;
>
> - if
> (node->tree->attributes & HFS_TREE_VARIDXKEYS)
> + if
> (node->tree->attributes & HFS_TREE_VARIDXKEYS ||
> +
> node->tree->cnid
> == HFSPLUS_ATTR_CNID)
>
> tmp = hfs_bnode_read_u16(node, key_off) +
> 2;
>
> else
>
> tmp = node->tree->max_key_len + 2;
> diff --git a/fs/hfsplus/brec.c b/fs/hfsplus/brec.c
> old mode 100644
> new mode 100755
> index 2a734cf..298d4e4
> --- a/fs/hfsplus/brec.c
> +++ b/fs/hfsplus/brec.c
> @@ -36,7 +36,8 @@ u16 hfs_brec_keylen(struct hfs_bnode
> *node, u16 rec)
> return 0;
>
> if ((node->type == HFS_NODE_INDEX)
> &&
> -
> !(node->tree->attributes &
> HFS_TREE_VARIDXKEYS)) {
> +
> !(node->tree->attributes &
> HFS_TREE_VARIDXKEYS) &&
> +
> (node->tree->cnid !=
> HFSPLUS_ATTR_CNID)) {
> retval =
> node->tree->max_key_len + 2;
> } else {
> recoff =
> hfs_bnode_read_u16(node,
> @@ -151,12 +152,13 @@ skip:
>
> /* get index key */
>
> hfs_bnode_read_key(new_node, fd->search_key, 14);
> -
> __hfs_brec_find(fd->bnode, fd);
> +
> __hfs_brec_find(fd->bnode, fd, hfs_find_rec_by_key);
>
>
> hfs_bnode_put(new_node);
> new_node = NULL;
>
> - if
> (tree->attributes & HFS_TREE_VARIDXKEYS)
> + if
> ((tree->attributes & HFS_TREE_VARIDXKEYS) ||
> +
> (tree->cnid == HFSPLUS_ATTR_CNID))
>
> key_len = be16_to_cpu(fd->search_key->key_len) + 2;
> else {
>
> fd->search_key->key_len =
> @@ -201,7 +203,7 @@ again:
> hfs_bnode_put(node);
> node = fd->bnode =
> parent;
>
> - __hfs_brec_find(node,
> fd);
> + __hfs_brec_find(node,
> fd, hfs_find_rec_by_key);
> goto again;
> }
> hfs_bnode_write_u16(node,
> @@ -367,12 +369,13 @@ again:
> parent = hfs_bnode_find(tree,
> node->parent);
> if (IS_ERR(parent))
> return
> PTR_ERR(parent);
> - __hfs_brec_find(parent, fd);
> + __hfs_brec_find(parent, fd,
> hfs_find_rec_by_key);
> hfs_bnode_dump(parent);
> rec = fd->record;
>
> /* size difference between old and new
> key */
> - if (tree->attributes &
> HFS_TREE_VARIDXKEYS)
> + if ((tree->attributes &
> HFS_TREE_VARIDXKEYS) ||
> +
> (tree->cnid == HFSPLUS_ATTR_CNID))
> newkeylen =
> hfs_bnode_read_u16(node, 14) + 2;
> else
> fd->keylength =
> newkeylen = tree->max_key_len + 2;
> @@ -427,7 +430,7 @@ skip:
>
> hfs_bnode_read_key(new_node, fd->search_key, 14);
> cnid =
> cpu_to_be32(new_node->this);
>
> -
> __hfs_brec_find(fd->bnode, fd);
> +
> __hfs_brec_find(fd->bnode, fd, hfs_find_rec_by_key);
> hfs_brec_insert(fd,
> &cnid, sizeof(cnid));
>
> hfs_bnode_put(fd->bnode);
>
> hfs_bnode_put(new_node);
> @@ -495,13 +498,15 @@ static int hfs_btree_inc_height(struct
> hfs_btree *tree)
> /* insert old root
> idx into new root */
> node->parent =
> tree->root;
> if (node->type ==
> HFS_NODE_LEAF ||
> -
> tree->attributes & HFS_TREE_VARIDXKEYS)
> +
> tree->attributes &
> HFS_TREE_VARIDXKEYS ||
> +
> tree->cnid == HFSPLUS_ATTR_CNID)
>
> key_size = hfs_bnode_read_u16(node, 14) + 2;
> else
>
> key_size = tree->max_key_len + 2;
>
> hfs_bnode_copy(new_node, 14, node, 14, key_size);
>
> - if
> (!(tree->attributes & HFS_TREE_VARIDXKEYS)) {
> + if
> (!(tree->attributes & HFS_TREE_VARIDXKEYS)
> &&
> +
> (tree->cnid != HFSPLUS_ATTR_CNID)) {
>
> key_size = tree->max_key_len + 2;
>
> hfs_bnode_write_u16(new_node, 14, tree->max_key_len);
> }
> diff --git a/fs/hfsplus/btree.c b/fs/hfsplus/btree.c
> old mode 100644
> new mode 100755
> index 21023d9..44294af
> --- a/fs/hfsplus/btree.c
> +++ b/fs/hfsplus/btree.c
> @@ -98,6 +98,14 @@ struct hfs_btree *hfs_btree_open(struct
> super_block *sb, u32 id)
>
> set_bit(HFSPLUS_SB_CASEFOLD,
> &HFSPLUS_SB(sb)->flags);
> }
> break;
> + case HFSPLUS_ATTR_CNID:
> + if
> (tree->max_key_len != HFSPLUS_ATTR_KEYLEN - sizeof(u16))
> {
> +
> printk(KERN_ERR "hfs: invalid attributes max_key_len %d\n",
> +
> tree->max_key_len);
> +
> goto fail_page;
> + }
> + tree->keycmp =
> hfsplus_attr_bin_cmp_key;
> + break;
> default:
> printk(KERN_ERR "hfs:
> unknown B*Tree requested\n");
> goto fail_page;
> diff --git a/fs/hfsplus/catalog.c b/fs/hfsplus/catalog.c
> old mode 100644
> new mode 100755
> index ec2a9c2..c285c8d
> --- a/fs/hfsplus/catalog.c
> +++ b/fs/hfsplus/catalog.c
> @@ -45,7 +45,8 @@ void hfsplus_cat_build_key(struct
> super_block *sb, hfsplus_btree_key *key,
>
> key->cat.parent =
> cpu_to_be32(parent);
> if (str) {
> - hfsplus_asc2uni(sb,
> &key->cat.name, str->name, str->len);
> + hfsplus_asc2uni(sb,
> &key->cat.name, HFSPLUS_MAX_STRLEN,
> +
> str->name,
> str->len);
> len =
> be16_to_cpu(key->cat.name.length);
> } else {
>
> key->cat.name.length = 0;
> @@ -167,7 +168,8 @@ static int
> hfsplus_fill_cat_thread(struct super_block *sb,
> entry->type = cpu_to_be16(type);
> entry->thread.reserved = 0;
> entry->thread.parentID =
> cpu_to_be32(parentid);
> - hfsplus_asc2uni(sb,
> &entry->thread.nodeName, str->name, str->len);
> + hfsplus_asc2uni(sb,
> &entry->thread.nodeName, HFSPLUS_MAX_STRLEN,
> +
> str->name, str->len);
> return 10 +
> be16_to_cpu(entry->thread.nodeName.length) * 2;
> }
>
> @@ -198,7 +200,7 @@ int hfsplus_find_cat(struct super_block
> *sb, u32 cnid,
>
> hfsplus_cat_build_key_uni(fd->search_key,
>
> be32_to_cpu(tmp.thread.parentID),
>
> &tmp.thread.nodeName);
> - return hfs_brec_find(fd);
> + return hfs_brec_find(fd,
> hfs_find_rec_by_key);
> }
>
> int hfsplus_create_cat(u32 cnid, struct inode *dir,
> @@ -221,7 +223,7 @@ int hfsplus_create_cat(u32 cnid, struct
> inode *dir,
>
> S_ISDIR(inode->i_mode) ?
>
> HFSPLUS_FOLDER_THREAD : HFSPLUS_FILE_THREAD,
> dir->i_ino, str);
> - err = hfs_brec_find(&fd);
> + err = hfs_brec_find(&fd,
> hfs_find_rec_by_key);
> if (err != -ENOENT) {
> if (!err)
>
> err = -EEXIST;
> @@ -233,7 +235,7 @@ int hfsplus_create_cat(u32 cnid, struct
> inode *dir,
>
> hfsplus_cat_build_key(sb, fd.search_key,
> dir->i_ino, str);
> entry_size =
> hfsplus_cat_build_record(&entry, cnid, inode);
> - err = hfs_brec_find(&fd);
> + err = hfs_brec_find(&fd,
> hfs_find_rec_by_key);
> if (err != -ENOENT) {
> /* panic? */
> if (!err)
> @@ -253,7 +255,7 @@ int hfsplus_create_cat(u32 cnid, struct
> inode *dir,
>
> err1:
> hfsplus_cat_build_key(sb, fd.search_key,
> cnid, NULL);
> - if (!hfs_brec_find(&fd))
> + if (!hfs_brec_find(&fd,
> hfs_find_rec_by_key))
>
> hfs_brec_remove(&fd);
> err2:
> hfs_find_exit(&fd);
> @@ -279,7 +281,7 @@ int hfsplus_delete_cat(u32 cnid, struct
> inode *dir, struct qstr *str)
> int len;
>
>
> hfsplus_cat_build_key(sb, fd.search_key, cnid, NULL);
> - err =
> hfs_brec_find(&fd);
> + err =
> hfs_brec_find(&fd, hfs_find_rec_by_key);
> if (err)
>
> goto out;
>
> @@ -296,7 +298,7 @@ int hfsplus_delete_cat(u32 cnid, struct
> inode *dir, struct qstr *str)
> } else
>
> hfsplus_cat_build_key(sb, fd.search_key, dir->i_ino,
> str);
>
> - err = hfs_brec_find(&fd);
> + err = hfs_brec_find(&fd,
> hfs_find_rec_by_key);
> if (err)
> goto out;
>
> @@ -326,7 +328,7 @@ int hfsplus_delete_cat(u32 cnid, struct
> inode *dir, struct qstr *str)
> goto out;
>
> hfsplus_cat_build_key(sb, fd.search_key,
> cnid, NULL);
> - err = hfs_brec_find(&fd);
> + err = hfs_brec_find(&fd,
> hfs_find_rec_by_key);
> if (err)
> goto out;
>
> @@ -337,6 +339,12 @@ int hfsplus_delete_cat(u32 cnid, struct
> inode *dir, struct qstr *str)
> dir->i_size--;
> dir->i_mtime = dir->i_ctime =
> CURRENT_TIME_SEC;
> hfsplus_mark_inode_dirty(dir,
> HFSPLUS_I_CAT_DIRTY);
> +
> + if (type == HFSPLUS_FILE || type ==
> HFSPLUS_FOLDER) {
> + if
> (HFSPLUS_SB(sb)->attr_tree)
> +
> hfsplus_delete_all_attrs(dir, cnid);
> + }
> +
> out:
> hfs_find_exit(&fd);
>
> @@ -363,7 +371,7 @@ int hfsplus_rename_cat(u32 cnid,
>
> /* find the old dir entry and read the
> data */
> hfsplus_cat_build_key(sb,
> src_fd.search_key, src_dir->i_ino, src_name);
> - err = hfs_brec_find(&src_fd);
> + err = hfs_brec_find(&src_fd,
> hfs_find_rec_by_key);
> if (err)
> goto out;
> if (src_fd.entrylength >
> sizeof(entry) || src_fd.entrylength < 0) {
> @@ -376,7 +384,7 @@ int hfsplus_rename_cat(u32 cnid,
>
> /* create new dir entry with the data
> from the old entry */
> hfsplus_cat_build_key(sb,
> dst_fd.search_key, dst_dir->i_ino, dst_name);
> - err = hfs_brec_find(&dst_fd);
> + err = hfs_brec_find(&dst_fd,
> hfs_find_rec_by_key);
> if (err != -ENOENT) {
> if (!err)
>
> err = -EEXIST;
> @@ -391,7 +399,7 @@ int hfsplus_rename_cat(u32 cnid,
>
> /* finally remove the old entry */
> hfsplus_cat_build_key(sb,
> src_fd.search_key, src_dir->i_ino, src_name);
> - err = hfs_brec_find(&src_fd);
> + err = hfs_brec_find(&src_fd,
> hfs_find_rec_by_key);
> if (err)
> goto out;
> err = hfs_brec_remove(&src_fd);
> @@ -402,7 +410,7 @@ int hfsplus_rename_cat(u32 cnid,
>
> /* remove old thread entry */
> hfsplus_cat_build_key(sb,
> src_fd.search_key, cnid, NULL);
> - err = hfs_brec_find(&src_fd);
> + err = hfs_brec_find(&src_fd,
> hfs_find_rec_by_key);
> if (err)
> goto out;
> type = hfs_bnode_read_u16(src_fd.bnode,
> src_fd.entryoffset);
> @@ -414,7 +422,7 @@ int hfsplus_rename_cat(u32 cnid,
> hfsplus_cat_build_key(sb,
> dst_fd.search_key, cnid, NULL);
> entry_size = hfsplus_fill_cat_thread(sb,
> &entry, type,
> dst_dir->i_ino,
> dst_name);
> - err = hfs_brec_find(&dst_fd);
> + err = hfs_brec_find(&dst_fd,
> hfs_find_rec_by_key);
> if (err != -ENOENT) {
> if (!err)
>
> err = -EEXIST;
> diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c
> old mode 100644
> new mode 100755
> index 6b9f921..40ceeab
> --- a/fs/hfsplus/dir.c
> +++ b/fs/hfsplus/dir.c
> @@ -138,7 +138,7 @@ static int hfsplus_readdir(struct file
> *filp, void *dirent, filldir_t filldir)
> if (err)
> return err;
> hfsplus_cat_build_key(sb, fd.search_key,
> inode->i_ino, NULL);
> - err = hfs_brec_find(&fd);
> + err = hfs_brec_find(&fd,
> hfs_find_rec_by_key);
> if (err)
> goto out;
>
> @@ -508,6 +508,10 @@ const struct inode_operations
> hfsplus_dir_inode_operations = {
> .symlink =
> hfsplus_symlink,
> .mknod
> = hfsplus_mknod,
> .rename
> = hfsplus_rename,
> + .setxattr =
> hfsplus_setxattr,
> + .getxattr =
> hfsplus_getxattr,
> + .listxattr =
> hfsplus_listxattr,
> + .removexattr =
> hfsplus_removexattr,
> };
>
> const struct file_operations hfsplus_dir_operations = {
> diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c
> old mode 100644
> new mode 100755
> index 5849e3e..87e59e9
> --- a/fs/hfsplus/extents.c
> +++ b/fs/hfsplus/extents.c
> @@ -95,7 +95,7 @@ static void
> __hfsplus_ext_write_extent(struct inode *inode,
>
> HFSPLUS_IS_RSRC(inode) ?
>
> HFSPLUS_TYPE_RSRC : HFSPLUS_TYPE_DATA);
>
> - res = hfs_brec_find(fd);
> + res = hfs_brec_find(fd,
> hfs_find_rec_by_key);
> if (hip->extent_state &
> HFSPLUS_EXT_NEW) {
> if (res != -ENOENT)
>
> return;
> @@ -154,7 +154,7 @@ static inline int
> __hfsplus_ext_read_extent(struct hfs_find_data *fd,
>
> hfsplus_ext_build_key(fd->search_key,
> cnid, block, type);
> fd->key->ext.cnid = 0;
> - res = hfs_brec_find(fd);
> + res = hfs_brec_find(fd,
> hfs_find_rec_by_key);
> if (res && res != -ENOENT)
> return res;
> if (fd->key->ext.cnid !=
> fd->search_key->ext.cnid ||
> diff --git a/fs/hfsplus/hfsplus_fs.h
> b/fs/hfsplus/hfsplus_fs.h
> old mode 100644
> new mode 100755
> index 558dbb4..03ed580
> --- a/fs/hfsplus/hfsplus_fs.h
> +++ b/fs/hfsplus/hfsplus_fs.h
> @@ -23,6 +23,7 @@
> #define DBG_SUPER 0x00000010
> #define DBG_EXTENT 0x00000020
> #define DBG_BITMAP 0x00000040
> +#define DBG_ATTR_MOD 0x00000080
>
> #if 0
> #define DBG_MASK
> (DBG_EXTENT|DBG_INODE|DBG_BNODE_MOD)
> @@ -223,6 +224,7 @@ struct hfsplus_inode_info {
> #define HFSPLUS_I_CAT_DIRTY
> 1 /* has changes in the catalog tree */
> #define HFSPLUS_I_EXT_DIRTY
> 2 /* has changes in the extent tree */
> #define HFSPLUS_I_ALLOC_DIRTY
> 3 /* has changes in the allocation file
> */
> +#define HFSPLUS_I_ATTR_DIRTY
> 4 /* has changes in the attributes tree
> */
>
> #define HFSPLUS_IS_RSRC(inode) \
> test_bit(HFSPLUS_I_RSRC,
> &HFSPLUS_I(inode)->flags)
> @@ -302,7 +304,7 @@ static inline unsigned short
> hfsplus_min_io_size(struct super_block *sb)
> #define hfs_brec_remove hfsplus_brec_remove
> #define hfs_find_init hfsplus_find_init
> #define hfs_find_exit hfsplus_find_exit
> -#define __hfs_brec_find __hplusfs_brec_find
> +#define __hfs_brec_find __hfsplus_brec_find
> #define hfs_brec_find hfsplus_brec_find
> #define hfs_brec_read hfsplus_brec_read
> #define hfs_brec_goto hfsplus_brec_goto
> @@ -324,10 +326,33 @@ static inline unsigned short
> hfsplus_min_io_size(struct super_block *sb)
> */
> #define HFSPLUS_IOC_BLESS _IO('h', 0x80)
>
> +typedef int (*search_strategy_t)(struct hfs_bnode *,
> +
> struct hfs_find_data *,
> +
> int *, int *, int *);
> +
> /*
> * Functions in any *.c used in other files
> */
>
> +/* attributes.c */
> +int hfsplus_create_attr_tree_cache(void);
> +void hfsplus_destroy_attr_tree_cache(void);
> +hfsplus_attr_entry *hfsplus_alloc_attr_entry(void);
> +void hfsplus_destroy_attr_entry(hfsplus_attr_entry
> *entry_p);
> +int hfsplus_attr_bin_cmp_key(const hfsplus_btree_key *,
> + const
> hfsplus_btree_key *);
> +int hfsplus_attr_build_key(struct super_block *,
> hfsplus_btree_key *,
> +
> u32, const char *);
> +void hfsplus_attr_build_key_uni(hfsplus_btree_key *key,
> +
> u32 cnid,
> +
> struct
> hfsplus_attr_unistr *name);
> +int hfsplus_find_attr(struct super_block *, u32,
> +
> const char *, struct hfs_find_data *);
> +int hfsplus_attr_exists(struct inode *inode, const char
> *name);
> +int hfsplus_create_attr(struct inode *, const char *, const
> void *, size_t);
> +int hfsplus_delete_attr(struct inode *, const char *);
> +int hfsplus_delete_all_attrs(struct inode *dir, u32 cnid);
> +
> /* bitmap.c */
> int hfsplus_block_allocate(struct super_block *, u32, u32,
> u32 *);
> int hfsplus_block_free(struct super_block *, u32, u32);
> @@ -369,8 +394,15 @@ int hfs_brec_remove(struct
> hfs_find_data *);
> /* bfind.c */
> int hfs_find_init(struct hfs_btree *, struct hfs_find_data
> *);
> void hfs_find_exit(struct hfs_find_data *);
> -int __hfs_brec_find(struct hfs_bnode *, struct
> hfs_find_data *);
> -int hfs_brec_find(struct hfs_find_data *);
> +int hfs_find_1st_rec_by_cnid(struct hfs_bnode *,
> +
> struct hfs_find_data *,
> +
> int *, int *, int *);
> +int hfs_find_rec_by_key(struct hfs_bnode *,
> +
> struct hfs_find_data *,
> +
> int *, int *, int *);
> +int __hfs_brec_find(struct hfs_bnode *, struct
> hfs_find_data *,
> +
> search_strategy_t);
> +int hfs_brec_find(struct hfs_find_data *,
> search_strategy_t);
> int hfs_brec_read(struct hfs_find_data *, void *, int);
> int hfs_brec_goto(struct hfs_find_data *, int);
>
> @@ -422,6 +454,7 @@ int hfsplus_setxattr(struct dentry
> *dentry, const char *name,
> ssize_t hfsplus_getxattr(struct dentry *dentry, const char
> *name,
>
> void *value, size_t size);
> ssize_t hfsplus_listxattr(struct dentry *dentry, char
> *buffer, size_t size);
> +int hfsplus_removexattr(struct dentry *dentry, const char
> *name);
>
> /* options.c */
> int hfsplus_parse_options(char *, struct hfsplus_sb_info
> *);
> @@ -446,7 +479,7 @@ int hfsplus_strcmp(const struct
> hfsplus_unistr *,
> int hfsplus_uni2asc(struct super_block *,
> const struct
> hfsplus_unistr *, char *, int *);
> int hfsplus_asc2uni(struct super_block *,
> - struct hfsplus_unistr
> *, const char *, int);
> + struct hfsplus_unistr
> *, int, const char *, int);
> int hfsplus_hash_dentry(const struct dentry *dentry,
> const struct inode
> *inode, struct qstr *str);
> int hfsplus_compare_dentry(const struct dentry *parent,
> diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
> old mode 100644
> new mode 100755
> index 3d8b4a6..98a6210
> --- a/fs/hfsplus/inode.c
> +++ b/fs/hfsplus/inode.c
> @@ -342,6 +342,18 @@ int hfsplus_file_fsync(struct file
> *file, loff_t start, loff_t end,
>
> error = error2;
> }
>
> + if
> (test_and_clear_bit(HFSPLUS_I_ATTR_DIRTY,
> &hip->flags)) {
> + if
> (sbi->attr_tree) {
> +
> error2 =
> +
> filemap_write_and_wait(
> +
>
> sbi->attr_tree->inode->i_mapping);
> + if
> (!error)
> +
> error = error2;
> + } else {
> +
> printk(KERN_ERR "hfs: sync non-existent attributes
> tree\n");
> + }
> + }
> +
> if
> (test_and_clear_bit(HFSPLUS_I_ALLOC_DIRTY,
> &hip->flags)) {
> error2 =
> filemap_write_and_wait(sbi->alloc_file->i_mapping);
> if (!error)
> @@ -363,6 +375,7 @@ static const struct inode_operations
> hfsplus_file_inode_operations = {
> .setxattr =
> hfsplus_setxattr,
> .getxattr =
> hfsplus_getxattr,
> .listxattr =
> hfsplus_listxattr,
> + .removexattr =
> hfsplus_removexattr,
> };
>
> static const struct file_operations hfsplus_file_operations
> = {
> diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
> old mode 100644
> new mode 100755
> index fdafb2d..5a7c91e
> --- a/fs/hfsplus/super.c
> +++ b/fs/hfsplus/super.c
> @@ -118,6 +118,7 @@ static int
> hfsplus_system_write_inode(struct inode *inode)
> case HFSPLUS_ATTR_CNID:
> fork =
> &vhdr->attr_file;
> tree =
> sbi->attr_tree;
> + break;
> default:
> return -EIO;
> }
> @@ -185,6 +186,12 @@ static int hfsplus_sync_fs(struct
> super_block *sb, int wait)
> error2 =
> filemap_write_and_wait(sbi->ext_tree->inode->i_mapping);
> if (!error)
> error = error2;
> + if (sbi->attr_tree) {
> + error2 =
> +
> filemap_write_and_wait(sbi->attr_tree->inode->i_mapping);
> + if (!error)
> +
> error = error2;
> + }
> error2 =
> filemap_write_and_wait(sbi->alloc_file->i_mapping);
> if (!error)
> error = error2;
> @@ -272,6 +279,7 @@ static void hfsplus_put_super(struct
> super_block *sb)
> hfsplus_sync_fs(sb,
> 1);
> }
>
> + hfs_btree_close(sbi->attr_tree);
> hfs_btree_close(sbi->cat_tree);
> hfs_btree_close(sbi->ext_tree);
> iput(sbi->alloc_file);
> @@ -468,12 +476,19 @@ static int hfsplus_fill_super(struct
> super_block *sb, void *data, int silent)
> printk(KERN_ERR "hfs:
> failed to load catalog file\n");
> goto
> out_close_ext_tree;
> }
> + if (vhdr->attr_file.total_blocks !=
> 0) {
> + sbi->attr_tree =
> hfs_btree_open(sb, HFSPLUS_ATTR_CNID);
> + if
> (!sbi->attr_tree) {
> +
> printk(KERN_ERR "hfs: failed to load attributes file\n");
> +
> goto out_close_cat_tree;
> + }
> + }
>
> inode = hfsplus_iget(sb,
> HFSPLUS_ALLOC_CNID);
> if (IS_ERR(inode)) {
> printk(KERN_ERR "hfs:
> failed to load allocation file\n");
> err =
> PTR_ERR(inode);
> - goto
> out_close_cat_tree;
> + goto
> out_close_attr_tree;
> }
> sbi->alloc_file = inode;
>
> @@ -553,6 +568,8 @@ out_put_root:
> sb->s_root = NULL;
> out_put_alloc_file:
> iput(sbi->alloc_file);
> +out_close_attr_tree:
> + hfs_btree_close(sbi->attr_tree);
> out_close_cat_tree:
> hfs_btree_close(sbi->cat_tree);
> out_close_ext_tree:
> @@ -626,15 +643,30 @@ static int __init
> init_hfsplus_fs(void)
> hfsplus_init_once);
> if (!hfsplus_inode_cachep)
> return -ENOMEM;
> +
> + err = hfsplus_create_attr_tree_cache();
> + if (err)
> + goto
> destroy_inode_cache;
> +
> err =
> register_filesystem(&hfsplus_fs_type);
> if (err)
> -
> kmem_cache_destroy(hfsplus_inode_cachep);
> + goto
> destroy_attr_tree_cache;
> +
> + return 0;
> +
> +destroy_attr_tree_cache:
> + hfsplus_destroy_attr_tree_cache();
> +
> +destroy_inode_cache:
> +
> kmem_cache_destroy(hfsplus_inode_cachep);
> +
> return err;
> }
>
> static void __exit exit_hfsplus_fs(void)
> {
>
> unregister_filesystem(&hfsplus_fs_type);
> + hfsplus_destroy_attr_tree_cache();
>
> kmem_cache_destroy(hfsplus_inode_cachep);
> }
>
> diff --git a/fs/hfsplus/unicode.c b/fs/hfsplus/unicode.c
> old mode 100644
> new mode 100755
> index a32998f..2c2e47d
> --- a/fs/hfsplus/unicode.c
> +++ b/fs/hfsplus/unicode.c
> @@ -295,7 +295,8 @@ static inline u16
> *decompose_unichar(wchar_t uc, int *size)
> return hfsplus_decompose_table + (off /
> 4);
> }
>
> -int hfsplus_asc2uni(struct super_block *sb, struct
> hfsplus_unistr *ustr,
> +int hfsplus_asc2uni(struct super_block *sb,
> + struct
> hfsplus_unistr *ustr, int max_unistr_len,
> const
> char *astr, int len)
> {
> int size, dsize, decompose;
> @@ -303,7 +304,7 @@ int hfsplus_asc2uni(struct super_block
> *sb, struct hfsplus_unistr *ustr,
> wchar_t c;
>
> decompose =
> !test_bit(HFSPLUS_SB_NODECOMPOSE,
> &HFSPLUS_SB(sb)->flags);
> - while (outlen < HFSPLUS_MAX_STRLEN
> && len > 0) {
> + while (outlen < max_unistr_len
> && len > 0) {
> size =
> asc2unichar(sb, astr, len, &c);
>
> if (decompose)
> @@ -311,7 +312,7 @@ int hfsplus_asc2uni(struct super_block
> *sb, struct hfsplus_unistr *ustr,
> else
>
> dstr = NULL;
> if (dstr) {
> - if
> (outlen + dsize > HFSPLUS_MAX_STRLEN)
> + if
> (outlen + dsize > max_unistr_len)
>
> break;
> do
> {
>
> ustr->unicode[outlen++] =
> cpu_to_be16(*dstr++);
> --
> 1.7.9.5
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v2 4/4] hfsplus: add support of manipulation by attributes file
2012-10-01 11:24 ` Hin-Tak Leung
@ 2012-10-01 11:52 ` Vyacheslav Dubeyko
0 siblings, 0 replies; 3+ messages in thread
From: Vyacheslav Dubeyko @ 2012-10-01 11:52 UTC (permalink / raw)
To: htl10; +Cc: linux-fsdevel, Andrew Morton, Christoph Hellwig, Al Viro
Hi Hin-Tak,
On Mon, 2012-10-01 at 12:24 +0100, Hin-Tak Leung wrote:
> --- On Sun, 23/9/12, Vyacheslav Dubeyko <slava@dubeyko.com> wrote:
>
> > Hi,
> >
> > This patch adds support of manipulation by attributes file.
> >
> > With the best regards,
> > Vyacheslav Dubeyko.
> > ---
> > From: Vyacheslav Dubeyko <slava@dubeyko.com>
> > Subject: [PATCH v2 4/4] hfsplus: add support of manipulation
> > by attributes file
> >
> > This patch adds support of manipulation by attributes file.
> >
> > Reported-by: Hin-Tak Leung <htl10@users.sourceforge.net>
> > Signed-off-by: Vyacheslav Dubeyko <slava@dubeyko.com>
>
> Tested-by: Hin-Tak Leung <htl10@users.sourceforge.net>
>
Thank you.
> Tried these 4 patches -together with the 5th which acted on code reviews and feedback. Works okay and fixed the two minor problems I had work v 1 (dubious warnings and interactions with selinux's use of extended atttributes).
>
> There is a small problem though - this set of patches changes the file modes of some of the files, as seen below - just scroll further down... The other patches also touch the file modes where files are modified.
>
> Hin-Tak
>
> > ---
> > fs/hfsplus/bfind.c
> > | 79
> > ++++++++++++++++++++++++++++++++++++++++-------
> > fs/hfsplus/bnode.c | 6
> > ++--
> > fs/hfsplus/brec.c
> > | 23 ++++++++------
> > fs/hfsplus/btree.c | 8
> > +++++
> > fs/hfsplus/catalog.c | 36
> > ++++++++++++---------
> > fs/hfsplus/dir.c |
> > 6 +++-
> > fs/hfsplus/extents.c | 4 +--
> > fs/hfsplus/hfsplus_fs.h | 41
> > +++++++++++++++++++++---
> > fs/hfsplus/inode.c
> > | 13 ++++++++
> > fs/hfsplus/super.c
> > | 36 +++++++++++++++++++--
> > fs/hfsplus/unicode.c | 7 +++--
> > 11 files changed, 210 insertions(+), 49 deletions(-)
> > mode change 100644 => 100755 fs/hfsplus/bfind.c
> > mode change 100644 => 100755 fs/hfsplus/bnode.c
> > mode change 100644 => 100755 fs/hfsplus/brec.c
> > mode change 100644 => 100755 fs/hfsplus/btree.c
> > mode change 100644 => 100755 fs/hfsplus/catalog.c
> > mode change 100644 => 100755 fs/hfsplus/dir.c
> > mode change 100644 => 100755 fs/hfsplus/extents.c
> > mode change 100644 => 100755 fs/hfsplus/hfsplus_fs.h
> > mode change 100644 => 100755 fs/hfsplus/inode.c
> > mode change 100644 => 100755 fs/hfsplus/super.c
> > mode change 100644 => 100755 fs/hfsplus/unicode.c
>
> Here - the file modes should not be touched...
>
You are right. This is my mistake that was made during path set preparation.
As I can understand, these file mode changes were not adopted during adding to the -mm tree.
With the best regards,
Vyacheslav Dubeyko.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2012-10-01 11:53 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-09-23 14:49 [PATCH v2 4/4] hfsplus: add support of manipulation by attributes file Vyacheslav Dubeyko
2012-10-01 11:24 ` Hin-Tak Leung
2012-10-01 11:52 ` Vyacheslav Dubeyko
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).