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

2016-07-06 Thread LastAvengers
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 
 #include 
 #include 
+#include 
 
 /* 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

[PATCH 1/2] xattr support for ext2fs

2016-07-06 Thread LastAvengers
Hi all,
Here is the result of the first stage of my GSoC project.
The xattr support for ext2fs has implemented.

This patch is base on cascardo's previous work[1],
Only 2 namespaces ("user." and  "gnu.") are supported,
as other namespaces are useless on hurd now.

thanks for braunr and teythoon's mentoring ;)

[1]: https://savannah.gnu.org/patch/?5126
--
Best regards,
Shengyu Zhang.

---
 ext2fs/Makefile  |   3 +-
 ext2fs/ext2_fs.h |   3 +-
 ext2fs/ext2fs.h  |  13 +
 ext2fs/ialloc.c  |   2 +
 ext2fs/xattr.c   | 866 +++
 ext2fs/xattr.h   |  85 ++
 6 files changed, 970 insertions(+), 2 deletions(-)
 create mode 100644 ext2fs/xattr.c
 create mode 100644 ext2fs/xattr.h

diff --git a/ext2fs/Makefile b/ext2fs/Makefile
index 88f8f46..0c2f4a2 100644
--- a/ext2fs/Makefile
+++ b/ext2fs/Makefile
@@ -21,7 +21,8 @@ makemode := server
 
 target = ext2fs
 SRCS = balloc.c dir.c ext2fs.c getblk.c hyper.c ialloc.c \
-   inode.c pager.c pokel.c truncate.c storeinfo.c msg.c xinl.c
+   inode.c pager.c pokel.c truncate.c storeinfo.c msg.c xinl.c \
+   xattr.c
 OBJS = $(SRCS:.c=.o)
 HURDLIBS = diskfs pager iohelp fshelp store ports ihash shouldbeinlibc
 LDLIBS = -lpthread $(and $(HAVE_LIBBZ2),-lbz2) $(and $(HAVE_LIBZ),-lz)
diff --git a/ext2fs/ext2_fs.h b/ext2fs/ext2_fs.h
index b1caeef..019ba15 100644
--- a/ext2fs/ext2_fs.h
+++ b/ext2fs/ext2_fs.h
@@ -462,6 +462,7 @@ struct ext2_super_block {
 ( EXT2_SB(sb)->s_feature_incompat & (mask) )
 
 #define EXT2_FEATURE_COMPAT_DIR_PREALLOC0x0001
+#define EXT2_FEATURE_COMPAT_EXT_ATTR0x0008
 
 #define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER0x0001
 #define EXT2_FEATURE_RO_COMPAT_LARGE_FILE0x0002
@@ -470,7 +471,7 @@ struct ext2_super_block {
 #define EXT2_FEATURE_INCOMPAT_COMPRESSION0x0001
 #define EXT2_FEATURE_INCOMPAT_FILETYPE0x0002
 
-#define EXT2_FEATURE_COMPAT_SUPP0
+#define EXT2_FEATURE_COMPAT_SUPPEXT2_FEATURE_COMPAT_EXT_ATTR
 #define EXT2_FEATURE_INCOMPAT_SUPPEXT2_FEATURE_INCOMPAT_FILETYPE
 #define EXT2_FEATURE_RO_COMPAT_SUPP(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
  EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
diff --git a/ext2fs/ext2fs.h b/ext2fs/ext2fs.h
index 070d5bd..bbf7a0c 100644
--- a/ext2fs/ext2fs.h
+++ b/ext2fs/ext2fs.h
@@ -17,6 +17,9 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
+#ifndef _EXT2FS_H
+#define _EXT2FS_H
+
 #include 
 #include 
 #include 
@@ -571,3 +574,13 @@ extern void _ext2_panic (const char *, const char *, ...)
 
 extern void ext2_warning (const char *, ...)
  __attribute__ ((format (printf, 1, 2)));
+
+/*  */
+/* xattr.c */
+
+error_t ext2_list_xattr (struct node *np, char *buffer, int *len);
+error_t ext2_get_xattr (struct node *np, const char *name, char *value, int 
*len);
+error_t ext2_set_xattr (struct node *np, const char *name, const char *value, 
int len, int flags);
+error_t ext2_free_xattr_block (struct node *np);
+
+#endif
diff --git a/ext2fs/ialloc.c b/ext2fs/ialloc.c
index 2809371..71bfb8c 100644
--- a/ext2fs/ialloc.c
+++ b/ext2fs/ialloc.c
@@ -62,6 +62,8 @@ diskfs_free_node (struct node *np, mode_t old_mode)
 
   ext2_debug ("freeing inode %u", inum);
 
+  ext2_free_xattr_block (np);
+
   pthread_spin_lock (&global_lock);
 
   if (inum < EXT2_FIRST_INO (sblock) || inum > sblock->s_inodes_count)
diff --git a/ext2fs/xattr.c b/ext2fs/xattr.c
new file mode 100644
index 000..1e298dcb
--- /dev/null
+++ b/ext2fs/xattr.c
@@ -0,0 +1,866 @@
+ /* Ext2 support for extended attributes
+
+   Copyright (C) 2006, 2016 Free Software Foundation, Inc.
+
+   Written by Thadeu Lima de Souza Cascardo 
+   and Shengyu Zhang 
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ext2fs.h"
+#include "xattr.h"
+#include 
+#include 
+#include 
+
+struct _xattr_prefix
+{
+  int index;
+  char *prefix;
+  ssize_t size;
+};
+
+/* Prefixes are represented as numbers when stored in ext2 filesystems. */
+struct _xattr_prefix
+xattr_prefixes[] =
+{
+  {
+  1, "user.", sizeof "user." - 1},
+  {
+  7, "gnu.", sizeof "gnu." - 1},
+  {
+  0, NULL, 0}
+};
+
+/*
+ * Given an attribute name in full_name, the ext2 number (index) and
+ * suffix name (name) are gi

[bug #48372] read with size 0 from fifo blocks

2016-07-06 Thread Kalle Olavi Niemitalo
Follow-up Comment #4, bug #48372 (project hurd):

IEEE Std 1003.1, 2013 Edition makes nbyte==0 a special case in the read and
pread functions, but I don't see similar special cases in the recv, recvfrom,
and recvmsg functions.  AFAICT, those should consume the message from a
message-based socket even if the buffer has zero length, unless MSG_PEEK is
specified.

pflocal/io.c (S_io_read) calls pipe_read, which calls pipe_recv (pipe,
noblock, 0, source, data, data_len, amount, 0,0,0,0).

pflocal/socket.c (S_socket_recv) calls pipe_recv (..., control, control_len,
ports, num_ports).  In hurd/socket.defs (socket_recv), those correspond to
output parameters, so I believe they are not included in the request message
and the mig-generated code will ensure that e.g. control != NULL.

I think pipe_read should then apply the shortcut behavior only if (amount == 0
&& data_only).  That way, the change would not affect recv, recvfrom, and
recvmsg.

___

Reply to this item at:

  

___
  Message sent via/by Savannah
  http://savannah.gnu.org/