bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 2/2] Using xattr to store translator record


From: LastAvengers
Subject: [PATCH 2/2] Using xattr to store translator record
Date: Wed, 6 Jul 2016 11:56:11 +0000

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.

--
Best regards,
Shengyu Zhang.

---
 ext2fs/inode.c | 156 +++++++++++++++++++++++++++++----------------------------
 1 file changed, 80 insertions(+), 76 deletions(-)

diff --git a/ext2fs/inode.c b/ext2fs/inode.c
index ccc8d69..be163d5 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)
+      daddr_t blkno;
+      struct ext2_inode *di;
+
+      di = dino_ref (np->cache_id);
+      blkno = di->i_translator;
+
+      if (blkno)
     {
-      dino_deref (di);
-      diskfs_end_catch_exception ();
-      return ENOSPC;
-    }
+      ext2_warning("Old tranlator record found, clear it");
 
-      di->i_translator = blkno;
-      diskfs_node_disknode (np)->info_i_translator = blkno;
-      record_global_poke (di);
+      /* 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_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;
+      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.9.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]