Re: [RFC PATCH v7 1/2] Btrfs: Add a new ioctl to get the label of a mounted file system

2012-12-21 Thread Stefan Behrens

On 12/21/2012 07:42, Jeff Liu wrote:

On 12/21/2012 04:18 AM, Goffredo Baroncelli wrote:

On 12/20/2012 09:43 AM, Jeff Liu wrote:

+static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg)
+{
+   struct btrfs_root *root = BTRFS_I(fdentry(file)-d_inode)-root;
+   const char *label = root-fs_info-super_copy-label;
+   int ret;
+
+   mutex_lock(root-fs_info-volume_mutex);
+   ret = copy_to_user(arg, label, strlen(label));


Sorry for pointing out my doubt too late, but should we trust
super_copy-label ?
An user could insert a usb-key with a btrfs filesystem with a label
without zero. In this case strlen() could access outside
super_copy-label[].

Thank you for letting me be aware of this situation.

First of all, if the user set label via btrfs tools, he can not make it
length exceeding BTRFS_LABLE_SIZE - 1.

If the user does that through codes wrote by himself like:
btrfslabel.c-set_label_unmounted(), he can do that.
However, it most likely he did that for evil purpose or any other reasons?


I think that it should be quite easy to alter artificially a filesystem
to crash the kernel. So I not consider this as big problem. However *in
case* of a further cycle of this patch I suggest to replace strlen()
with strnlen().

I don't think we should replace strlen() with strnlen() since it's
totally wrong if the length of label is more than BTRFS_LABEL_SIZE -1,
we can not just truncating the label and return it in this case.
Add BUG_ON(strlen(label)  BTRFS_LABEL_SIZE - 1) is reasonable instead.


Don't allow users to attack the kernel! This would add a severe security 
issue. A BUG_ON() is something that you can use before the code would 
crash anyway, to prevent any additional damage and to help in debugging. 
A BUG() is not a method to report or handle user errors.


A Linux system is supposed to run until it is shutdown by the 
administrator, not until somebody inserts an USB stick.


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


[PATCH 2/3] Btrfs: use wrapper page_offset

2012-12-21 Thread Miao Xie
Use wrapper page_offset to get byte-offset into filesystem object for page.

Signed-off-by: Liu Bo liubo2...@cn.fujitsu.com
Signed-off-by: Miao Xie mi...@cn.fujitsu.com
---
 fs/btrfs/disk-io.c|  2 +-
 fs/btrfs/extent_io.c  | 24 +++-
 fs/btrfs/inode.c  |  5 ++---
 fs/btrfs/relocation.c |  2 +-
 4 files changed, 15 insertions(+), 18 deletions(-)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 65f0367..e045203 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -420,7 +420,7 @@ static int btree_read_extent_buffer_pages(struct btrfs_root 
*root,
 static int csum_dirty_buffer(struct btrfs_root *root, struct page *page)
 {
struct extent_io_tree *tree;
-   u64 start = (u64)page-index  PAGE_CACHE_SHIFT;
+   u64 start = page_offset(page);
u64 found_start;
struct extent_buffer *eb;
 
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 1b319df..bda36fe 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -1834,7 +1834,7 @@ int test_range_bit(struct extent_io_tree *tree, u64 
start, u64 end,
  */
 static void check_page_uptodate(struct extent_io_tree *tree, struct page *page)
 {
-   u64 start = (u64)page-index  PAGE_CACHE_SHIFT;
+   u64 start = page_offset(page);
u64 end = start + PAGE_CACHE_SIZE - 1;
if (test_range_bit(tree, start, end, EXTENT_UPTODATE, 1, NULL))
SetPageUptodate(page);
@@ -1846,7 +1846,7 @@ static void check_page_uptodate(struct extent_io_tree 
*tree, struct page *page)
  */
 static void check_page_locked(struct extent_io_tree *tree, struct page *page)
 {
-   u64 start = (u64)page-index  PAGE_CACHE_SHIFT;
+   u64 start = page_offset(page);
u64 end = start + PAGE_CACHE_SIZE - 1;
if (!test_range_bit(tree, start, end, EXTENT_LOCKED, 0, NULL))
unlock_page(page);
@@ -1960,7 +1960,7 @@ int repair_io_failure(struct btrfs_fs_info *fs_info, u64 
start,
return -EIO;
}
bio-bi_bdev = dev-bdev;
-   bio_add_page(bio, page, length, start-page_offset(page));
+   bio_add_page(bio, page, length, start - page_offset(page));
btrfsic_submit_bio(WRITE_SYNC, bio);
wait_for_completion(compl);
 
@@ -2293,8 +2293,7 @@ static void end_bio_extent_writepage(struct bio *bio, int 
err)
struct page *page = bvec-bv_page;
tree = BTRFS_I(page-mapping-host)-io_tree;
 
-   start = ((u64)page-index  PAGE_CACHE_SHIFT) +
-bvec-bv_offset;
+   start = page_offset(page) + bvec-bv_offset;
end = start + bvec-bv_len - 1;
 
if (bvec-bv_offset == 0  bvec-bv_len == PAGE_CACHE_SIZE)
@@ -2353,8 +2352,7 @@ static void end_bio_extent_readpage(struct bio *bio, int 
err)
 (long int)bio-bi_bdev);
tree = BTRFS_I(page-mapping-host)-io_tree;
 
-   start = ((u64)page-index  PAGE_CACHE_SHIFT) +
-   bvec-bv_offset;
+   start = page_offset(page) + bvec-bv_offset;
end = start + bvec-bv_len - 1;
 
if (bvec-bv_offset == 0  bvec-bv_len == PAGE_CACHE_SIZE)
@@ -2471,7 +2469,7 @@ static int __must_check submit_one_bio(int rw, struct bio 
*bio,
struct extent_io_tree *tree = bio-bi_private;
u64 start;
 
-   start = ((u64)page-index  PAGE_CACHE_SHIFT) + bvec-bv_offset;
+   start = page_offset(page) + bvec-bv_offset;
 
bio-bi_private = NULL;
 
@@ -2595,7 +2593,7 @@ static int __extent_read_full_page(struct extent_io_tree 
*tree,
   unsigned long *bio_flags)
 {
struct inode *inode = page-mapping-host;
-   u64 start = (u64)page-index  PAGE_CACHE_SHIFT;
+   u64 start = page_offset(page);
u64 page_end = start + PAGE_CACHE_SIZE - 1;
u64 end;
u64 cur = start;
@@ -2806,7 +2804,7 @@ static int __extent_writepage(struct page *page, struct 
writeback_control *wbc,
struct inode *inode = page-mapping-host;
struct extent_page_data *epd = data;
struct extent_io_tree *tree = epd-tree;
-   u64 start = (u64)page-index  PAGE_CACHE_SHIFT;
+   u64 start = page_offset(page);
u64 delalloc_start;
u64 page_end = start + PAGE_CACHE_SIZE - 1;
u64 end;
@@ -3674,7 +3672,7 @@ int extent_invalidatepage(struct extent_io_tree *tree,
  struct page *page, unsigned long offset)
 {
struct extent_state *cached_state = NULL;
-   u64 start = ((u64)page-index  PAGE_CACHE_SHIFT);
+   u64 start = page_offset(page);
u64 end = start + PAGE_CACHE_SIZE - 1;
size_t blocksize = page-mapping-host-i_sb-s_blocksize;
 
@@ -3700,7 +3698,7 @@ int try_release_extent_state(struct extent_map_tree *map,
 struct extent_io_tree *tree, struct page *page,
 gfp_t mask)
 {
-   u64 start = (u64)page-index  

[PATCH 1/3] Btrfs: fix missing write access release in btrfs_ioctl_resize()

2012-12-21 Thread Miao Xie
We forget to give up the write access after we find some device operation
is going on. Fix it.

Signed-off-by: Miao Xie mi...@cn.fujitsu.com
---
 fs/btrfs/ioctl.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 7624212..679b82c 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -1338,7 +1338,9 @@ static noinline int btrfs_ioctl_resize(struct file *file,
 
if (atomic_xchg(root-fs_info-mutually_exclusive_operation_running,
1)) {
-   pr_info(btrfs: dev add/delete/balance/replace/resize operation 
in progress\n);
+   pr_info(btrfs: dev add/delete/balance/replace/resize operation
+in progress\n);
+   mnt_drop_write_file(file);
return -EINPROGRESS;
}
 
-- 
1.7.11.7
--
To unsubscribe from this list: send the line unsubscribe linux-btrfs in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/3] Btrfs: fix resize a readonly device

2012-12-21 Thread Miao Xie
We should not resize a readonly device, fix it.

Signed-off-by: Miao Xie mi...@cn.fujitsu.com
---
 fs/btrfs/ioctl.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 679b82c..668475c 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -1364,6 +1364,7 @@ static noinline int btrfs_ioctl_resize(struct file *file,
printk(KERN_INFO btrfs: resizing devid %llu\n,
   (unsigned long long)devid);
}
+
device = btrfs_find_device(root-fs_info, devid, NULL, NULL);
if (!device) {
printk(KERN_INFO btrfs: resizer unable to find device %llu\n,
@@ -1371,9 +1372,10 @@ static noinline int btrfs_ioctl_resize(struct file *file,
ret = -EINVAL;
goto out_free;
}
-   if (device-fs_devices  device-fs_devices-seeding) {
+
+   if (!device-writeable) {
printk(KERN_INFO btrfs: resizer unable to apply on 
-  seeding device %llu\n,
+  readonly device %llu\n,
   (unsigned long long)devid);
ret = -EINVAL;
goto out_free;
-- 
1.7.11.7
--
To unsubscribe from this list: send the line unsubscribe linux-btrfs in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/3] Btrfs: fix trivial error in btrfs_ioctl_resize()

2012-12-21 Thread Miao Xie
This patch fixes the following problem:
- improper return value
- unnecessary read-only check

Signed-off-by: Miao Xie mi...@cn.fujitsu.com
---
 fs/btrfs/ioctl.c | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 668475c..773865f 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -1326,9 +1326,6 @@ static noinline int btrfs_ioctl_resize(struct file *file,
int ret = 0;
int mod = 0;
 
-   if (root-fs_info-sb-s_flags  MS_RDONLY)
-   return -EROFS;
-
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
 
@@ -1361,6 +1358,10 @@ static noinline int btrfs_ioctl_resize(struct file *file,
*devstr = '\0';
devstr = vol_args-name;
devid = simple_strtoull(devstr, end, 10);
+   if (!devid) {
+   ret = -EINVAL;
+   goto out_free;
+   }
printk(KERN_INFO btrfs: resizing devid %llu\n,
   (unsigned long long)devid);
}
@@ -1369,7 +1370,7 @@ static noinline int btrfs_ioctl_resize(struct file *file,
if (!device) {
printk(KERN_INFO btrfs: resizer unable to find device %llu\n,
   (unsigned long long)devid);
-   ret = -EINVAL;
+   ret = -ENODEV;
goto out_free;
}
 
@@ -1377,7 +1378,7 @@ static noinline int btrfs_ioctl_resize(struct file *file,
printk(KERN_INFO btrfs: resizer unable to apply on 
   readonly device %llu\n,
   (unsigned long long)devid);
-   ret = -EINVAL;
+   ret = -EPERM;
goto out_free;
}
 
@@ -1399,7 +1400,7 @@ static noinline int btrfs_ioctl_resize(struct file *file,
}
 
if (device-is_tgtdev_for_dev_replace) {
-   ret = -EINVAL;
+   ret = -EPERM;
goto out_free;
}
 
-- 
1.7.11.7
--
To unsubscribe from this list: send the line unsubscribe linux-btrfs in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/3] Btrfs: fix missing write access release in btrfs_ioctl_resize()

2012-12-21 Thread Miao Xie
On Fri, 21 Dec 2012 11:22:52 +0100, Stefan Behrens wrote:
 On Fri, 21 Dec 2012 17:19:20 +0800, Miao Xie wrote:
 -pr_info(btrfs: dev add/delete/balance/replace/resize operation 
 in progress\n);
 +pr_info(btrfs: dev add/delete/balance/replace/resize operation
 + in progress\n);
 +mnt_drop_write_file(file);
 
 grep and vi cannot do searches spanning multiple lines. That's why I
 created this pr_info() line with more than 80 columns (in accordance
 with Documentation/CodingStyle BTW (never break user-visible strings)).
 

You are right. I will update the patch soon.

Thanks
Miao

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


Re: [RFC PATCH v7 1/2] Btrfs: Add a new ioctl to get the label of a mounted file system

2012-12-21 Thread Goffredo Baroncelli
On 12/21/2012 07:42 AM, Jeff Liu wrote:
 Hi Goffredo,
 
 On 12/21/2012 04:18 AM, Goffredo Baroncelli wrote:
 HI Jeff,

 On 12/20/2012 09:43 AM, Jeff Liu wrote:
 With the new ioctl(2) BTRFS_IOC_GET_FSLABEL we can fetch the label of a 
 mounted file system.

 Signed-off-by: Jie Liu jeff@oracle.com
 Signed-off-by: Anand Jain anand.j...@oracle.com
 Cc: Miao Xie mi...@cn.fujitsu.com
 Cc: Goffredo Baroncelli kreij...@inwind.it
 Cc: David Sterba dste...@suse.cz
 [...]
 +static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg)
 +{
 +   struct btrfs_root *root = BTRFS_I(fdentry(file)-d_inode)-root;
 +   const char *label = root-fs_info-super_copy-label;
 +   int ret;
 +
 +   mutex_lock(root-fs_info-volume_mutex);
 +   ret = copy_to_user(arg, label, strlen(label));

 Sorry for pointing out my doubt too late, but should we trust
 super_copy-label ?
 An user could insert a usb-key with a btrfs filesystem with a label
 without zero. In this case strlen() could access outside
 super_copy-label[].
 Thank you for letting me be aware of this situation.
 
 First of all, if the user set label via btrfs tools, he can not make it
 length exceeding BTRFS_LABLE_SIZE - 1.
 
 If the user does that through codes wrote by himself like:
 btrfslabel.c-set_label_unmounted(), he can do that.
 However, it most likely he did that for evil purpose or any other reasons?

I think the most likely case is the evil purpose.


 I think that it should be quite easy to alter artificially a filesystem
 to crash the kernel. So I not consider this as big problem. However *in
 case* of a further cycle of this patch I suggest to replace strlen()
 with strnlen().
 I don't think we should replace strlen() with strnlen() since it's
 totally wrong if the length of label is more than BTRFS_LABEL_SIZE -1,
 we can not just truncating the label and return it in this case.

This for me is sufficient, or we could copy all the label buffer,
without further check:

copy_to_user(arg, label, BTRFS_LABEL_SIZE)


 Add BUG_ON(strlen(label)  BTRFS_LABEL_SIZE - 1) is reasonable instead.

I agree with Stefan, this is not a correct use of BUG_ON; a warning is
sufficient (there is un-correct data read from disk).

 
 Thanks,
 -Jeff

 +   mutex_unlock(root-fs_info-volume_mutex);
 +
 +   return ret ? -EFAULT : 0;
 +}
 +
  long btrfs_ioctl(struct file *file, unsigned int
 cmd, unsigned long arg)
  {
 @@ -3797,6 +3810,8 @@ long btrfs_ioctl(struct file *file, unsigned int
 return btrfs_ioctl_qgroup_create(root, argp);
 case BTRFS_IOC_QGROUP_LIMIT:
 return btrfs_ioctl_qgroup_limit(root, argp);
 +   case BTRFS_IOC_GET_FSLABEL:
 +   return btrfs_ioctl_get_fslabel(file, argp);
 }
  
 return -ENOTTY;
 diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h
 index 731e287..5b2cbef 100644
 --- a/fs/btrfs/ioctl.h
 +++ b/fs/btrfs/ioctl.h
 @@ -451,6 +451,8 @@ struct btrfs_ioctl_send_args {
struct btrfs_ioctl_qgroup_create_args)
  #define BTRFS_IOC_QGROUP_LIMIT _IOR(BTRFS_IOCTL_MAGIC, 43, \
struct btrfs_ioctl_qgroup_limit_args)
 +#define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 49, \
 +  char[BTRFS_LABEL_SIZE])
  #define BTRFS_IOC_GET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, \
   struct btrfs_ioctl_get_dev_stats)
  #endif


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


-- 
gpg @keyserver.linux.it: Goffredo Baroncelli (kreijackATinwind.it
Key fingerprint BBF5 1610 0B64 DAC6 5F7D  17B2 0EDA 9B37 8B82 E0B5
--
To unsubscribe from this list: send the line unsubscribe linux-btrfs in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


add, remove; how about merge?

2012-12-21 Thread Gene Czarcinski

I am new at this btrfs stuff!

As I understand it, you can add a physical disk or partition and have 
data spread into the new space.  You can also move data off a disk or 
partition and then remove it.


Has any though  been given to being able merge to existing (separate) 
btrfs volumes into a single volume?


Alternatively, how about at tool for transfering a subvolume from one 
pool to another?  I tried using fsarchiver but that did not work out too 
well.


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


Re: add, remove; how about merge?

2012-12-21 Thread Hugo Mills
On Fri, Dec 21, 2012 at 01:16:59PM -0500, Gene Czarcinski wrote:
 I am new at this btrfs stuff!
 
 As I understand it, you can add a physical disk or partition and
 have data spread into the new space.  You can also move data off a
 disk or partition and then remove it.
 
 Has any though  been given to being able merge to existing
 (separate) btrfs volumes into a single volume?

   This would be difficult to do in kernel space -- you'd have to
change the UUIDs on all the metadata on at least one of the
filesystems, plus handle (correctly) all of the numberspace clashes
correctly -- subvolume trees, virtual address space, and probably a
load that I've forgotten as well. Given what I'm about to say, I can't
see this happening any time soon.

 Alternatively, how about at tool for transfering a subvolume from
 one pool to another?  I tried using fsarchiver but that did not work
 out too well.

   You want send/receive. It's in the mainline kernel, and you'll need
a recent userspace, but it allows you to transfer subvolumes cleanly
and losslessly between filesystems.

   Hugo.

-- 
=== Hugo Mills: hugo@... carfax.org.uk | darksatanic.net | lug.org.uk ===
  PGP key: 515C238D from wwwkeys.eu.pgp.net or http://www.carfax.org.uk
--- You are not stuck in traffic:  you are traffic. ---


signature.asc
Description: Digital signature


Re: add, remove; how about merge?

2012-12-21 Thread Remco Hosman - Yerf IT
I think thats possible with btrfs-send/receive

Remco

On Dec 21, 2012, at 7:16 PM, Gene Czarcinski g...@czarc.net wrote:

 I am new at this btrfs stuff!
 
 As I understand it, you can add a physical disk or partition and have data 
 spread into the new space.  You can also move data off a disk or partition 
 and then remove it.
 
 Has any though  been given to being able merge to existing (separate) btrfs 
 volumes into a single volume?
 
 Alternatively, how about at tool for transfering a subvolume from one pool to 
 another?  I tried using fsarchiver but that did not work out too well.
 
 Gene
 --
 To unsubscribe from this list: send the line unsubscribe linux-btrfs in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html

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


[PATCH] Btrfs: overwrite existing csums when logging

2012-12-21 Thread Josef Bacik
Users were complaining about the warning in btrfs_log_parent_inode() because
we're returning -EEXIST.  This warning is gone in another patch but it's
still making us commit a transaction when we don't have to.  Basically
because we will log all csums in an ordered extent for an em we have the
chance of logging the same csums multiple times.  Since it's not that big of
a deal just allow csums to be over written in logs and that way we are safe.
This gets rid of the EEXIST and we log like we normally would.  Thanks,

Signed-off-by: Josef Bacik jba...@fusionio.com
---
 fs/btrfs/file-item.c |7 +++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index bd38cef..93ddc2e 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -835,6 +835,13 @@ insert:
ret = btrfs_insert_empty_item(trans, root, path, file_key,
  ins_size);
path-leave_spinning = 0;
+
+   /*
+* We can sometimes already have copied a csum into the log, that's ok
+* just overwrite it.
+*/
+   if (root-objectid == BTRFS_TREE_LOG_OBJECTID  ret == -EEXIST)
+   ret = 0;
if (ret  0)
goto fail_unlock;
if (ret != 0) {
-- 
1.7.7.6

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