summaryrefslogtreecommitdiff
path: root/debian/patches/xattr0002-ext2fs-using-xattr-to-store-translator-record.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/xattr0002-ext2fs-using-xattr-to-store-translator-record.patch')
-rw-r--r--debian/patches/xattr0002-ext2fs-using-xattr-to-store-translator-record.patch231
1 files changed, 231 insertions, 0 deletions
diff --git a/debian/patches/xattr0002-ext2fs-using-xattr-to-store-translator-record.patch b/debian/patches/xattr0002-ext2fs-using-xattr-to-store-translator-record.patch
new file mode 100644
index 00000000..b67606ba
--- /dev/null
+++ b/debian/patches/xattr0002-ext2fs-using-xattr-to-store-translator-record.patch
@@ -0,0 +1,231 @@
+From 8743e2f7c22c50bcc289c1a5ac093731f9d1638c Mon Sep 17 00:00:00 2001
+From: Shengyu Zhang <lastavengers@outlook.com>
+Date: Fri, 8 Jul 2016 00:21:52 +0200
+Subject: [PATCH hurd 2/6] ext2fs: using xattr to store translator record
+
+The purpose we implement xattr is storing passive translator in a
+more general way. Now passive translator record now can be stored
+using extended attributes. The new diskfs_{get,set}_translator()
+functions are also compatibility with the "legacy" passive translator
+record.
+
+Thanks for antrik's suggestions.
+---
+ ext2fs/inode.c | 158 +++++++++++++++++++++++++++++----------------------------
+ 1 file changed, 81 insertions(+), 77 deletions(-)
+
+diff --git a/ext2fs/inode.c b/ext2fs/inode.c
+index ccc8d69..175bc26 100644
+--- a/ext2fs/inode.c
++++ b/ext2fs/inode.c
+@@ -26,6 +26,7 @@
+ #include <sys/stat.h>
+ #include <sys/statfs.h>
+ #include <sys/statvfs.h>
++#include <sys/xattr.h>
+
+ /* these flags aren't actually defined by a header file yet, so temporarily
+ disable them if necessary. */
+@@ -540,81 +541,62 @@ error_t
+ diskfs_set_translator (struct node *np, const char *name, unsigned namelen,
+ struct protid *cred)
+ {
+- daddr_t blkno;
++ int len;
+ error_t err;
+- char buf[block_size];
+- struct ext2_inode *di;
+
+ assert (!diskfs_readonly);
+
+- if (sblock->s_creator_os != EXT2_OS_HURD)
+- return EOPNOTSUPP;
+-
+- if (namelen + 2 > block_size)
+- return ENAMETOOLONG;
+-
+ err = diskfs_catch_exception ();
+ if (err)
+ return err;
+
+- di = dino_ref (np->cache_id);
+- blkno = di->i_translator;
+-
+- if (namelen && !blkno)
++ /* If a old translator record found, clear it */
++ if (sblock->s_creator_os == EXT2_OS_HURD)
+ {
+- /* Allocate block for translator */
+- blkno =
+- ext2_new_block ((diskfs_node_disknode (np)->info.i_block_group
+- * EXT2_BLOCKS_PER_GROUP (sblock))
+- + sblock->s_first_data_block,
+- 0, 0, 0);
+- if (blkno == 0)
+- {
+- dino_deref (di);
+- diskfs_end_catch_exception ();
+- return ENOSPC;
+- }
++ daddr_t blkno;
++ struct ext2_inode *di;
+
+- di->i_translator = blkno;
+- diskfs_node_disknode (np)->info_i_translator = blkno;
+- record_global_poke (di);
++ di = dino_ref (np->cache_id);
++ blkno = di->i_translator;
+
+- np->dn_stat.st_blocks += 1 << log2_stat_blocks_per_fs_block;
+- np->dn_set_ctime = 1;
+- }
+- else if (!namelen && blkno)
+- {
+- /* Clear block for translator going away. */
+- di->i_translator = 0;
+- diskfs_node_disknode (np)->info_i_translator = 0;
+- record_global_poke (di);
+- ext2_free_blocks (blkno, 1);
+-
+- np->dn_stat.st_blocks -= 1 << log2_stat_blocks_per_fs_block;
+- np->dn_stat.st_mode &= ~S_IPTRANS;
+- np->dn_set_ctime = 1;
++ if (blkno)
++ {
++ ext2_warning("Old tranlator record found, clear it");
++
++ /* Clear block for translator going away. */
++ di->i_translator = 0;
++ diskfs_node_disknode (np)->info_i_translator = 0;
++ record_global_poke (di);
++ ext2_free_blocks (blkno, 1);
++
++ np->dn_stat.st_blocks -= 1 << log2_stat_blocks_per_fs_block;
++ np->dn_stat.st_mode &= ~S_IPTRANS;
++ np->dn_set_ctime = 1;
++ }
++ else
++ dino_deref (di);
+ }
+- else
+- dino_deref (di);
+
+- if (namelen)
+- {
+- void *blkptr;
+-
+- buf[0] = namelen & 0xFF;
+- buf[1] = (namelen >> 8) & 0xFF;
+- memcpy (buf + 2, name, namelen);
++ /* Use xattr to store translator record, with key "gnu.translator" */
++ err = ext2_get_xattr(np, "gnu.translator", NULL, &len);
++ if (err && err != ENODATA)
++ return err;
+
+- blkptr = disk_cache_block_ref (blkno);
+- memcpy (blkptr, buf, block_size);
+- record_global_poke (blkptr);
++ if (namelen && err == ENODATA)
++ {
++ err = ext2_set_xattr(np, "gnu.translator", name, namelen, XATTR_CREATE);
+
+ np->dn_stat.st_mode |= S_IPTRANS;
+ np->dn_set_ctime = 1;
+ }
++ else if (!namelen && !err)
++ {
++ err = ext2_set_xattr(np, "gnu.translator", NULL, 0, 0);
++ }
+
+ diskfs_end_catch_exception ();
+ return err;
++
+ }
+
+ /* Implement the diskfs_get_translator callback from the diskfs library.
+@@ -623,37 +605,59 @@ error_t
+ diskfs_get_translator (struct node *np, char **namep, unsigned *namelen)
+ {
+ error_t err = 0;
+- daddr_t blkno;
+- unsigned datalen;
+- void *transloc;
+- struct ext2_inode *di;
+-
+- assert (sblock->s_creator_os == EXT2_OS_HURD);
++ int datalen;
+
+ err = diskfs_catch_exception ();
+ if (err)
+ return err;
+
+- di = dino_ref (np->cache_id);
+- blkno = di->i_translator;
+- dino_deref (di);
+- assert (blkno);
+- transloc = disk_cache_block_ref (blkno);
+-
+- datalen =
+- ((unsigned char *)transloc)[0] + (((unsigned char *)transloc)[1] << 8);
+- if (datalen > block_size - 2)
+- err = EFTYPE; /* ? */
+- else
++ /* If a old translator record found, read it firstly */
++ if (sblock->s_creator_os == EXT2_OS_HURD)
+ {
+- *namep = malloc (datalen);
+- if (!*namep)
+- err = ENOMEM;
+- else
+- memcpy (*namep, transloc + 2, datalen);
++ daddr_t blkno;
++ void *transloc;
++ struct ext2_inode *di;
++
++ di = dino_ref (np->cache_id);
++ blkno = di->i_translator;
++ dino_deref (di);
++
++ if (blkno)
++ {
++ ext2_warning("This is a old translotor record, please update it");
++
++ transloc = disk_cache_block_ref (blkno);
++ datalen = ((unsigned char *)transloc)[0] +
++ (((unsigned char *)transloc)[1] << 8);
++ if (datalen > block_size - 2)
++ err = EFTYPE; /* ? */
++ else
++ {
++ *namep = malloc (datalen);
++ if (!*namep)
++ err = ENOMEM;
++ else
++ memcpy (*namep, transloc + 2, datalen);
++ }
++
++ disk_cache_block_deref (transloc);
++ diskfs_end_catch_exception ();
++
++ *namelen = datalen;
++ return err;
++ }
+ }
+
+- disk_cache_block_deref (transloc);
++ err = ext2_get_xattr (np, "gnu.translator", NULL, &datalen);
++ if (err)
++ return err;
++
++ *namep = malloc (datalen);
++ if (!*namep)
++ err = ENOMEM;
++ else
++ err = ext2_get_xattr (np, "gnu.translator", *namep, &datalen);
++
+ diskfs_end_catch_exception ();
+
+ *namelen = datalen;
+--
+2.8.1
+