Re: [RFC] NFS Support

2008-06-30 Thread Josef Bacik
On Sun, Jun 29, 2008 at 05:05:31AM +0530, Balaji Rao wrote:
 Hello,
 
 Here's a quick implementation of NFS support for btrfs. It works mostly. But
 its still a bit buggy. I suspect it has to do something with inode locking.
 When I unmount and mount a couple of times, it stops working i.e, when I do 
 an 
 'ls', it keeps waiting indefinitely. This is seen when accessing the 
 filesystem
 from a local mount point as well.
 
 Can anybody please review and tell me what stupid mistake I'm committing ? 


You may want to send things in patch form.  I'd recommend using the hg quilt
plugin, its nice for adding patches easily.
 
 
 #include linux/fs.h
 #include linux/types.h
 #include ctree.h
 #include disk-io.h
 #include btrfs_inode.h
 #include print-tree.h
 #include export.h
 
 static int btrfs_encode_fh(struct dentry *dentry, u32 *fh_in, int *max_len,
   int connectable)
 { struct inode *inode = dentry-d_inode;
   int len = *max_len;
   u64 objectid, root_objectid;
   u32 generation;
   __le32 *fh = (__force __le32 *) fh_in;
 
   if ((len  5 )|| (connectable  len  8)) {
   return 255;
   }

Magic numbers are a no-no.

   
   objectid = BTRFS_I(inode)-location.objectid;
   root_objectid = BTRFS_I(inode)-root-objectid;
   generation = inode-i_generation;
 
   len  = 5;
   fh[0] = cpu_to_le32((u32)(objectid  32));
   fh[1] = cpu_to_le32((u32)(objectid  0x));
   fh[2] = cpu_to_le32((u32)(root_objectid  32));
   fh[3] = cpu_to_le32((u32)(root_objectid  0x));
   fh[4] = cpu_to_le32(generation);
 
   if (connectable  !S_ISDIR(inode-i_mode)) {
   struct inode *parent;
 
   spin_lock(dentry-d_lock);
 
   parent = dentry-d_parent-d_inode;
   objectid = BTRFS_I(parent)-location.objectid;
   generation = parent-i_generation;
 
   fh[5] = cpu_to_le32((u32)(objectid  32));
   fh[6] = cpu_to_le32((u32)(objectid  0x));
   fh[7] = cpu_to_le32(generation);
 
   spin_unlock(dentry-d_lock);
 
   len += 3;

there is no need to take the d_lock here.

   }
   
   *max_len = len;
   return len;
 
 }
 
 static struct dentry * btrfs_get_dentry(struct super_block *sb,
   u64 objectid, u64 root_objectid, u32 generation)
 {
   struct inode *inode;
   struct dentry *result;
 
   inode = btrfs_ilookup(sb, objectid, root_objectid);
   if (IS_ERR(inode))
   return (void *)inode;
 
   if(generation != inode-i_generation) {
   iput(inode);
   return ERR_PTR(-ESTALE);
   }
 
   result = d_alloc_anon(inode);
   if(!result) {
   iput(inode);
   return ERR_PTR(-ENOMEM);
   }
 
   return result;
 }
 
 static struct dentry *btrfs_fh_to_parent(struct super_block *sb,
   struct fid *fid, int fh_len, int fh_type)
 {
   u64 objectid, root_objectid;
   u32 generation;
 
   if (fh_len  8 || fh_type != 8) {
   return NULL;
   }
 
 
   root_objectid = (u64)le32_to_cpu(fid-raw[2])  32;
   root_objectid |= (u64)le32_to_cpu(fid-raw[3]);
   objectid = (u64)le32_to_cpu(fid-raw[5])  32;
   objectid |= (u64)le32_to_cpu(fid-raw[6]);  
   generation = le32_to_cpu(fid-raw[7]);
 
   return btrfs_get_dentry(sb, objectid, root_objectid, generation);
 }
 
 static struct dentry *btrfs_fh_to_dentry(struct super_block *sb,
   struct fid *fid, int fh_len, int fh_type)
 {
   u64 objectid, root_objectid;
   u32 generation;
 
   if (fh_len  5 || fh_type  5) {
   return NULL;
   }
 
   objectid = (u64)le32_to_cpu(fid-raw[0])  32;
   objectid |= (u64)le32_to_cpu(fid-raw[1]);  
   root_objectid = (u64)le32_to_cpu(fid-raw[2])  32;
   root_objectid |= (u64)le32_to_cpu(fid-raw[3]);
   generation = le32_to_cpu(fid-raw[4]);
 
   return btrfs_get_dentry(sb, objectid, root_objectid, generation);
 }
 
 static struct dentry *btrfs_get_parent(struct dentry *child)
 {
   struct inode *dir = child-d_inode;
   struct inode *inode;
   struct dentry *parent;
   struct btrfs_root *root = BTRFS_I(dir)-root;
   struct btrfs_key key;
   struct btrfs_path *path;
   struct extent_buffer *leaf; 
   u32 nritems;
   int slot;
   u64 objectid;
   int ret;
 
   path = btrfs_alloc_path();
 
   key.objectid = dir-i_ino;
   btrfs_set_key_type(key, BTRFS_INODE_REF_KEY);
   key.offset = 0;
   ret = btrfs_search_slot(NULL, root, key, path, 0, 0);
   BUG_ON(ret == 0);
   ret = 0;
 
   leaf = path-nodes[0];
   slot = path-slots[0];
   nritems = btrfs_header_nritems(leaf);
   if (slot = nritems)
   return ERR_PTR(-EINVAL);
 
   btrfs_item_key_to_cpu(leaf, key, slot);
   if (key.objectid != 

Re: [PATCH] COW and checksumming ioctls

2008-06-30 Thread Christoph Hellwig
On Sun, Jun 22, 2008 at 10:10:06AM -0400, Chris Mason wrote:
 The idea is that backup programs already know how to do xattrs and can
 easily be changed to preserve them.  Every ioctl interface we
 create/make up has to be handed coded into the backup program.

Actually they don't.  Because of the mess we've created with the
xattr namespaces and the way e.g. ACLs are mapped into two of them
they will need to special case the interesting non-user attributes.

While sane backup applications already know about the inode flag word
because it contains lots of useful information for the existing
filesystems.

 I know xattrs are ugly, but we need to weigh the cost of the perfect
 interface with the availability of a common one.  Dave Chinner had
 talked about using xattrs to control file behavior in XFS as well, not
 sure if that ever happened.

I think I've successfully talked him out of it :)

--
To unsubscribe from this list: send the line unsubscribe linux-btrfs in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html