aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-09-19 20:17:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-09-19 20:17:32 -0400
commit50f2d407c09be74c77cf9d502d087398a5ba6055 (patch)
tree17c1b10bafc7a9769123d61f72d4c5249eee7c9f /fs
parentc2d7b49f42f50d7fc5cbfd195b785a128723fdf4 (diff)
parenta66e7cc626f42de6c745963fe0d807518fa49d39 (diff)
Merge branch 'for-linus' of git://github.com/chrismason/linux
* 'for-linus' of git://github.com/chrismason/linux: Btrfs: only clear the need lookup flag after the dentry is setup BTRFS: Fix lseek return value for error Btrfs: don't change inode flag of the dest clone file Btrfs: don't make a file partly checksummed through file clone Btrfs: fix pages truncation in btrfs_ioctl_clone() btrfs: fix d_off in the first dirent
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/file.c9
-rw-r--r--fs/btrfs/inode.c18
-rw-r--r--fs/btrfs/ioctl.c14
3 files changed, 30 insertions, 11 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 3c3abff731a7..a381cd22f518 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1817,6 +1817,11 @@ static loff_t btrfs_file_llseek(struct file *file, loff_t offset, int origin)
1817 goto out; 1817 goto out;
1818 case SEEK_DATA: 1818 case SEEK_DATA:
1819 case SEEK_HOLE: 1819 case SEEK_HOLE:
1820 if (offset >= i_size_read(inode)) {
1821 mutex_unlock(&inode->i_mutex);
1822 return -ENXIO;
1823 }
1824
1820 ret = find_desired_extent(inode, &offset, origin); 1825 ret = find_desired_extent(inode, &offset, origin);
1821 if (ret) { 1826 if (ret) {
1822 mutex_unlock(&inode->i_mutex); 1827 mutex_unlock(&inode->i_mutex);
@@ -1825,11 +1830,11 @@ static loff_t btrfs_file_llseek(struct file *file, loff_t offset, int origin)
1825 } 1830 }
1826 1831
1827 if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) { 1832 if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) {
1828 ret = -EINVAL; 1833 offset = -EINVAL;
1829 goto out; 1834 goto out;
1830 } 1835 }
1831 if (offset > inode->i_sb->s_maxbytes) { 1836 if (offset > inode->i_sb->s_maxbytes) {
1832 ret = -EINVAL; 1837 offset = -EINVAL;
1833 goto out; 1838 goto out;
1834 } 1839 }
1835 1840
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 4d14de6d121b..b2d004ad66a0 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -4018,7 +4018,8 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
4018 memcpy(&location, dentry->d_fsdata, sizeof(struct btrfs_key)); 4018 memcpy(&location, dentry->d_fsdata, sizeof(struct btrfs_key));
4019 kfree(dentry->d_fsdata); 4019 kfree(dentry->d_fsdata);
4020 dentry->d_fsdata = NULL; 4020 dentry->d_fsdata = NULL;
4021 d_clear_need_lookup(dentry); 4021 /* This thing is hashed, drop it for now */
4022 d_drop(dentry);
4022 } else { 4023 } else {
4023 ret = btrfs_inode_by_name(dir, dentry, &location); 4024 ret = btrfs_inode_by_name(dir, dentry, &location);
4024 } 4025 }
@@ -4085,7 +4086,15 @@ static void btrfs_dentry_release(struct dentry *dentry)
4085static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry, 4086static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,
4086 struct nameidata *nd) 4087 struct nameidata *nd)
4087{ 4088{
4088 return d_splice_alias(btrfs_lookup_dentry(dir, dentry), dentry); 4089 struct dentry *ret;
4090
4091 ret = d_splice_alias(btrfs_lookup_dentry(dir, dentry), dentry);
4092 if (unlikely(d_need_lookup(dentry))) {
4093 spin_lock(&dentry->d_lock);
4094 dentry->d_flags &= ~DCACHE_NEED_LOOKUP;
4095 spin_unlock(&dentry->d_lock);
4096 }
4097 return ret;
4089} 4098}
4090 4099
4091unsigned char btrfs_filetype_table[] = { 4100unsigned char btrfs_filetype_table[] = {
@@ -4125,7 +4134,8 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
4125 4134
4126 /* special case for "." */ 4135 /* special case for "." */
4127 if (filp->f_pos == 0) { 4136 if (filp->f_pos == 0) {
4128 over = filldir(dirent, ".", 1, 1, btrfs_ino(inode), DT_DIR); 4137 over = filldir(dirent, ".", 1,
4138 filp->f_pos, btrfs_ino(inode), DT_DIR);
4129 if (over) 4139 if (over)
4130 return 0; 4140 return 0;
4131 filp->f_pos = 1; 4141 filp->f_pos = 1;
@@ -4134,7 +4144,7 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
4134 if (filp->f_pos == 1) { 4144 if (filp->f_pos == 1) {
4135 u64 pino = parent_ino(filp->f_path.dentry); 4145 u64 pino = parent_ino(filp->f_path.dentry);
4136 over = filldir(dirent, "..", 2, 4146 over = filldir(dirent, "..", 2,
4137 2, pino, DT_DIR); 4147 filp->f_pos, pino, DT_DIR);
4138 if (over) 4148 if (over)
4139 return 0; 4149 return 0;
4140 filp->f_pos = 2; 4150 filp->f_pos = 2;
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 3351b1b24574..d11fd28efa6a 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -2177,6 +2177,11 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
2177 if (!(src_file->f_mode & FMODE_READ)) 2177 if (!(src_file->f_mode & FMODE_READ))
2178 goto out_fput; 2178 goto out_fput;
2179 2179
2180 /* don't make the dst file partly checksummed */
2181 if ((BTRFS_I(src)->flags & BTRFS_INODE_NODATASUM) !=
2182 (BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM))
2183 goto out_fput;
2184
2180 ret = -EISDIR; 2185 ret = -EISDIR;
2181 if (S_ISDIR(src->i_mode) || S_ISDIR(inode->i_mode)) 2186 if (S_ISDIR(src->i_mode) || S_ISDIR(inode->i_mode))
2182 goto out_fput; 2187 goto out_fput;
@@ -2226,6 +2231,10 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
2226 goto out_unlock; 2231 goto out_unlock;
2227 } 2232 }
2228 2233
2234 /* truncate page cache pages from target inode range */
2235 truncate_inode_pages_range(&inode->i_data, destoff,
2236 PAGE_CACHE_ALIGN(destoff + len) - 1);
2237
2229 /* do any pending delalloc/csum calc on src, one way or 2238 /* do any pending delalloc/csum calc on src, one way or
2230 another, and lock file content */ 2239 another, and lock file content */
2231 while (1) { 2240 while (1) {
@@ -2242,10 +2251,6 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
2242 btrfs_wait_ordered_range(src, off, len); 2251 btrfs_wait_ordered_range(src, off, len);
2243 } 2252 }
2244 2253
2245 /* truncate page cache pages from target inode range */
2246 truncate_inode_pages_range(&inode->i_data, off,
2247 ALIGN(off + len, PAGE_CACHE_SIZE) - 1);
2248
2249 /* clone data */ 2254 /* clone data */
2250 key.objectid = btrfs_ino(src); 2255 key.objectid = btrfs_ino(src);
2251 key.type = BTRFS_EXTENT_DATA_KEY; 2256 key.type = BTRFS_EXTENT_DATA_KEY;
@@ -2442,7 +2447,6 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
2442 if (endoff > inode->i_size) 2447 if (endoff > inode->i_size)
2443 btrfs_i_size_write(inode, endoff); 2448 btrfs_i_size_write(inode, endoff);
2444 2449
2445 BTRFS_I(inode)->flags = BTRFS_I(src)->flags;
2446 ret = btrfs_update_inode(trans, root, inode); 2450 ret = btrfs_update_inode(trans, root, inode);
2447 BUG_ON(ret); 2451 BUG_ON(ret);
2448 btrfs_end_transaction(trans, root); 2452 btrfs_end_transaction(trans, root);