diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-09-21 03:48:33 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-09-21 03:48:33 -0400 |
commit | f70cac8d9c7125f83048f8b3d1c60f5a041a165c (patch) | |
tree | 0d0efd72c1a41f973a919b16aac1d8210ed1ee30 /fs | |
parent | 4722cd7741c6404f967f7a7b8b666540b6c1663e (diff) | |
parent | 08aab447c56a5388cf0c768da476ad022f00fef8 (diff) |
Merge branch 'kprobes-test' of git://git.yxit.co.uk/linux into devel-stable
Diffstat (limited to 'fs')
-rw-r--r-- | fs/9p/v9fs_vfs.h | 6 | ||||
-rw-r--r-- | fs/9p/vfs_file.c | 36 | ||||
-rw-r--r-- | fs/9p/vfs_inode.c | 139 | ||||
-rw-r--r-- | fs/9p/vfs_inode_dotl.c | 86 | ||||
-rw-r--r-- | fs/9p/vfs_super.c | 2 | ||||
-rw-r--r-- | fs/block_dev.c | 7 | ||||
-rw-r--r-- | fs/btrfs/btrfs_inode.h | 6 | ||||
-rw-r--r-- | fs/btrfs/file-item.c | 4 | ||||
-rw-r--r-- | fs/btrfs/file.c | 16 | ||||
-rw-r--r-- | fs/btrfs/free-space-cache.c | 4 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 22 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 19 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 4 | ||||
-rw-r--r-- | fs/btrfs/xattr.c | 9 | ||||
-rw-r--r-- | fs/ceph/mds_client.c | 2 | ||||
-rw-r--r-- | fs/ceph/super.c | 4 | ||||
-rw-r--r-- | fs/ext4/ext4.h | 1 | ||||
-rw-r--r-- | fs/ext4/inode.c | 3 | ||||
-rw-r--r-- | fs/ext4/page-io.c | 18 | ||||
-rw-r--r-- | fs/fuse/dev.c | 12 | ||||
-rw-r--r-- | fs/fuse/inode.c | 3 | ||||
-rw-r--r-- | fs/namei.c | 33 | ||||
-rw-r--r-- | fs/ubifs/debug.h | 6 | ||||
-rw-r--r-- | fs/xfs/xfs_iops.c | 14 | ||||
-rw-r--r-- | fs/xfs/xfs_super.c | 36 |
25 files changed, 332 insertions, 160 deletions
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h index 46ce357ca1ab..410ffd6ceb5f 100644 --- a/fs/9p/v9fs_vfs.h +++ b/fs/9p/v9fs_vfs.h | |||
@@ -54,9 +54,9 @@ extern struct kmem_cache *v9fs_inode_cache; | |||
54 | 54 | ||
55 | struct inode *v9fs_alloc_inode(struct super_block *sb); | 55 | struct inode *v9fs_alloc_inode(struct super_block *sb); |
56 | void v9fs_destroy_inode(struct inode *inode); | 56 | void v9fs_destroy_inode(struct inode *inode); |
57 | struct inode *v9fs_get_inode(struct super_block *sb, int mode); | 57 | struct inode *v9fs_get_inode(struct super_block *sb, int mode, dev_t); |
58 | int v9fs_init_inode(struct v9fs_session_info *v9ses, | 58 | int v9fs_init_inode(struct v9fs_session_info *v9ses, |
59 | struct inode *inode, int mode); | 59 | struct inode *inode, int mode, dev_t); |
60 | void v9fs_evict_inode(struct inode *inode); | 60 | void v9fs_evict_inode(struct inode *inode); |
61 | ino_t v9fs_qid2ino(struct p9_qid *qid); | 61 | ino_t v9fs_qid2ino(struct p9_qid *qid); |
62 | void v9fs_stat2inode(struct p9_wstat *, struct inode *, struct super_block *); | 62 | void v9fs_stat2inode(struct p9_wstat *, struct inode *, struct super_block *); |
@@ -83,4 +83,6 @@ static inline void v9fs_invalidate_inode_attr(struct inode *inode) | |||
83 | v9inode->cache_validity |= V9FS_INO_INVALID_ATTR; | 83 | v9inode->cache_validity |= V9FS_INO_INVALID_ATTR; |
84 | return; | 84 | return; |
85 | } | 85 | } |
86 | |||
87 | int v9fs_open_to_dotl_flags(int flags); | ||
86 | #endif | 88 | #endif |
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index 3c173fcc2c5a..62857a810a79 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c | |||
@@ -65,7 +65,7 @@ int v9fs_file_open(struct inode *inode, struct file *file) | |||
65 | v9inode = V9FS_I(inode); | 65 | v9inode = V9FS_I(inode); |
66 | v9ses = v9fs_inode2v9ses(inode); | 66 | v9ses = v9fs_inode2v9ses(inode); |
67 | if (v9fs_proto_dotl(v9ses)) | 67 | if (v9fs_proto_dotl(v9ses)) |
68 | omode = file->f_flags; | 68 | omode = v9fs_open_to_dotl_flags(file->f_flags); |
69 | else | 69 | else |
70 | omode = v9fs_uflags2omode(file->f_flags, | 70 | omode = v9fs_uflags2omode(file->f_flags, |
71 | v9fs_proto_dotu(v9ses)); | 71 | v9fs_proto_dotu(v9ses)); |
@@ -169,7 +169,18 @@ static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl) | |||
169 | 169 | ||
170 | /* convert posix lock to p9 tlock args */ | 170 | /* convert posix lock to p9 tlock args */ |
171 | memset(&flock, 0, sizeof(flock)); | 171 | memset(&flock, 0, sizeof(flock)); |
172 | flock.type = fl->fl_type; | 172 | /* map the lock type */ |
173 | switch (fl->fl_type) { | ||
174 | case F_RDLCK: | ||
175 | flock.type = P9_LOCK_TYPE_RDLCK; | ||
176 | break; | ||
177 | case F_WRLCK: | ||
178 | flock.type = P9_LOCK_TYPE_WRLCK; | ||
179 | break; | ||
180 | case F_UNLCK: | ||
181 | flock.type = P9_LOCK_TYPE_UNLCK; | ||
182 | break; | ||
183 | } | ||
173 | flock.start = fl->fl_start; | 184 | flock.start = fl->fl_start; |
174 | if (fl->fl_end == OFFSET_MAX) | 185 | if (fl->fl_end == OFFSET_MAX) |
175 | flock.length = 0; | 186 | flock.length = 0; |
@@ -245,7 +256,7 @@ static int v9fs_file_getlock(struct file *filp, struct file_lock *fl) | |||
245 | 256 | ||
246 | /* convert posix lock to p9 tgetlock args */ | 257 | /* convert posix lock to p9 tgetlock args */ |
247 | memset(&glock, 0, sizeof(glock)); | 258 | memset(&glock, 0, sizeof(glock)); |
248 | glock.type = fl->fl_type; | 259 | glock.type = P9_LOCK_TYPE_UNLCK; |
249 | glock.start = fl->fl_start; | 260 | glock.start = fl->fl_start; |
250 | if (fl->fl_end == OFFSET_MAX) | 261 | if (fl->fl_end == OFFSET_MAX) |
251 | glock.length = 0; | 262 | glock.length = 0; |
@@ -257,17 +268,26 @@ static int v9fs_file_getlock(struct file *filp, struct file_lock *fl) | |||
257 | res = p9_client_getlock_dotl(fid, &glock); | 268 | res = p9_client_getlock_dotl(fid, &glock); |
258 | if (res < 0) | 269 | if (res < 0) |
259 | return res; | 270 | return res; |
260 | if (glock.type != F_UNLCK) { | 271 | /* map 9p lock type to os lock type */ |
261 | fl->fl_type = glock.type; | 272 | switch (glock.type) { |
273 | case P9_LOCK_TYPE_RDLCK: | ||
274 | fl->fl_type = F_RDLCK; | ||
275 | break; | ||
276 | case P9_LOCK_TYPE_WRLCK: | ||
277 | fl->fl_type = F_WRLCK; | ||
278 | break; | ||
279 | case P9_LOCK_TYPE_UNLCK: | ||
280 | fl->fl_type = F_UNLCK; | ||
281 | break; | ||
282 | } | ||
283 | if (glock.type != P9_LOCK_TYPE_UNLCK) { | ||
262 | fl->fl_start = glock.start; | 284 | fl->fl_start = glock.start; |
263 | if (glock.length == 0) | 285 | if (glock.length == 0) |
264 | fl->fl_end = OFFSET_MAX; | 286 | fl->fl_end = OFFSET_MAX; |
265 | else | 287 | else |
266 | fl->fl_end = glock.start + glock.length - 1; | 288 | fl->fl_end = glock.start + glock.length - 1; |
267 | fl->fl_pid = glock.proc_id; | 289 | fl->fl_pid = glock.proc_id; |
268 | } else | 290 | } |
269 | fl->fl_type = F_UNLCK; | ||
270 | |||
271 | return res; | 291 | return res; |
272 | } | 292 | } |
273 | 293 | ||
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 8bb5507e822f..e3c03db3c788 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -95,15 +95,18 @@ static int unixmode2p9mode(struct v9fs_session_info *v9ses, int mode) | |||
95 | /** | 95 | /** |
96 | * p9mode2unixmode- convert plan9 mode bits to unix mode bits | 96 | * p9mode2unixmode- convert plan9 mode bits to unix mode bits |
97 | * @v9ses: v9fs session information | 97 | * @v9ses: v9fs session information |
98 | * @mode: mode to convert | 98 | * @stat: p9_wstat from which mode need to be derived |
99 | * @rdev: major number, minor number in case of device files. | ||
99 | * | 100 | * |
100 | */ | 101 | */ |
101 | 102 | static int p9mode2unixmode(struct v9fs_session_info *v9ses, | |
102 | static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode) | 103 | struct p9_wstat *stat, dev_t *rdev) |
103 | { | 104 | { |
104 | int res; | 105 | int res; |
106 | int mode = stat->mode; | ||
105 | 107 | ||
106 | res = mode & 0777; | 108 | res = mode & S_IALLUGO; |
109 | *rdev = 0; | ||
107 | 110 | ||
108 | if ((mode & P9_DMDIR) == P9_DMDIR) | 111 | if ((mode & P9_DMDIR) == P9_DMDIR) |
109 | res |= S_IFDIR; | 112 | res |= S_IFDIR; |
@@ -116,9 +119,26 @@ static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode) | |||
116 | && (v9ses->nodev == 0)) | 119 | && (v9ses->nodev == 0)) |
117 | res |= S_IFIFO; | 120 | res |= S_IFIFO; |
118 | else if ((mode & P9_DMDEVICE) && (v9fs_proto_dotu(v9ses)) | 121 | else if ((mode & P9_DMDEVICE) && (v9fs_proto_dotu(v9ses)) |
119 | && (v9ses->nodev == 0)) | 122 | && (v9ses->nodev == 0)) { |
120 | res |= S_IFBLK; | 123 | char type = 0, ext[32]; |
121 | else | 124 | int major = -1, minor = -1; |
125 | |||
126 | strncpy(ext, stat->extension, sizeof(ext)); | ||
127 | sscanf(ext, "%c %u %u", &type, &major, &minor); | ||
128 | switch (type) { | ||
129 | case 'c': | ||
130 | res |= S_IFCHR; | ||
131 | break; | ||
132 | case 'b': | ||
133 | res |= S_IFBLK; | ||
134 | break; | ||
135 | default: | ||
136 | P9_DPRINTK(P9_DEBUG_ERROR, | ||
137 | "Unknown special type %c %s\n", type, | ||
138 | stat->extension); | ||
139 | }; | ||
140 | *rdev = MKDEV(major, minor); | ||
141 | } else | ||
122 | res |= S_IFREG; | 142 | res |= S_IFREG; |
123 | 143 | ||
124 | if (v9fs_proto_dotu(v9ses)) { | 144 | if (v9fs_proto_dotu(v9ses)) { |
@@ -131,7 +151,6 @@ static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode) | |||
131 | if ((mode & P9_DMSETVTX) == P9_DMSETVTX) | 151 | if ((mode & P9_DMSETVTX) == P9_DMSETVTX) |
132 | res |= S_ISVTX; | 152 | res |= S_ISVTX; |
133 | } | 153 | } |
134 | |||
135 | return res; | 154 | return res; |
136 | } | 155 | } |
137 | 156 | ||
@@ -242,13 +261,13 @@ void v9fs_destroy_inode(struct inode *inode) | |||
242 | } | 261 | } |
243 | 262 | ||
244 | int v9fs_init_inode(struct v9fs_session_info *v9ses, | 263 | int v9fs_init_inode(struct v9fs_session_info *v9ses, |
245 | struct inode *inode, int mode) | 264 | struct inode *inode, int mode, dev_t rdev) |
246 | { | 265 | { |
247 | int err = 0; | 266 | int err = 0; |
248 | 267 | ||
249 | inode_init_owner(inode, NULL, mode); | 268 | inode_init_owner(inode, NULL, mode); |
250 | inode->i_blocks = 0; | 269 | inode->i_blocks = 0; |
251 | inode->i_rdev = 0; | 270 | inode->i_rdev = rdev; |
252 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 271 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
253 | inode->i_mapping->a_ops = &v9fs_addr_operations; | 272 | inode->i_mapping->a_ops = &v9fs_addr_operations; |
254 | 273 | ||
@@ -335,7 +354,7 @@ error: | |||
335 | * | 354 | * |
336 | */ | 355 | */ |
337 | 356 | ||
338 | struct inode *v9fs_get_inode(struct super_block *sb, int mode) | 357 | struct inode *v9fs_get_inode(struct super_block *sb, int mode, dev_t rdev) |
339 | { | 358 | { |
340 | int err; | 359 | int err; |
341 | struct inode *inode; | 360 | struct inode *inode; |
@@ -348,7 +367,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode) | |||
348 | P9_EPRINTK(KERN_WARNING, "Problem allocating inode\n"); | 367 | P9_EPRINTK(KERN_WARNING, "Problem allocating inode\n"); |
349 | return ERR_PTR(-ENOMEM); | 368 | return ERR_PTR(-ENOMEM); |
350 | } | 369 | } |
351 | err = v9fs_init_inode(v9ses, inode, mode); | 370 | err = v9fs_init_inode(v9ses, inode, mode, rdev); |
352 | if (err) { | 371 | if (err) { |
353 | iput(inode); | 372 | iput(inode); |
354 | return ERR_PTR(err); | 373 | return ERR_PTR(err); |
@@ -435,11 +454,12 @@ void v9fs_evict_inode(struct inode *inode) | |||
435 | static int v9fs_test_inode(struct inode *inode, void *data) | 454 | static int v9fs_test_inode(struct inode *inode, void *data) |
436 | { | 455 | { |
437 | int umode; | 456 | int umode; |
457 | dev_t rdev; | ||
438 | struct v9fs_inode *v9inode = V9FS_I(inode); | 458 | struct v9fs_inode *v9inode = V9FS_I(inode); |
439 | struct p9_wstat *st = (struct p9_wstat *)data; | 459 | struct p9_wstat *st = (struct p9_wstat *)data; |
440 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); | 460 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); |
441 | 461 | ||
442 | umode = p9mode2unixmode(v9ses, st->mode); | 462 | umode = p9mode2unixmode(v9ses, st, &rdev); |
443 | /* don't match inode of different type */ | 463 | /* don't match inode of different type */ |
444 | if ((inode->i_mode & S_IFMT) != (umode & S_IFMT)) | 464 | if ((inode->i_mode & S_IFMT) != (umode & S_IFMT)) |
445 | return 0; | 465 | return 0; |
@@ -473,6 +493,7 @@ static struct inode *v9fs_qid_iget(struct super_block *sb, | |||
473 | struct p9_wstat *st, | 493 | struct p9_wstat *st, |
474 | int new) | 494 | int new) |
475 | { | 495 | { |
496 | dev_t rdev; | ||
476 | int retval, umode; | 497 | int retval, umode; |
477 | unsigned long i_ino; | 498 | unsigned long i_ino; |
478 | struct inode *inode; | 499 | struct inode *inode; |
@@ -496,8 +517,8 @@ static struct inode *v9fs_qid_iget(struct super_block *sb, | |||
496 | * later. | 517 | * later. |
497 | */ | 518 | */ |
498 | inode->i_ino = i_ino; | 519 | inode->i_ino = i_ino; |
499 | umode = p9mode2unixmode(v9ses, st->mode); | 520 | umode = p9mode2unixmode(v9ses, st, &rdev); |
500 | retval = v9fs_init_inode(v9ses, inode, umode); | 521 | retval = v9fs_init_inode(v9ses, inode, umode, rdev); |
501 | if (retval) | 522 | if (retval) |
502 | goto error; | 523 | goto error; |
503 | 524 | ||
@@ -532,6 +553,19 @@ v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, | |||
532 | } | 553 | } |
533 | 554 | ||
534 | /** | 555 | /** |
556 | * v9fs_at_to_dotl_flags- convert Linux specific AT flags to | ||
557 | * plan 9 AT flag. | ||
558 | * @flags: flags to convert | ||
559 | */ | ||
560 | static int v9fs_at_to_dotl_flags(int flags) | ||
561 | { | ||
562 | int rflags = 0; | ||
563 | if (flags & AT_REMOVEDIR) | ||
564 | rflags |= P9_DOTL_AT_REMOVEDIR; | ||
565 | return rflags; | ||
566 | } | ||
567 | |||
568 | /** | ||
535 | * v9fs_remove - helper function to remove files and directories | 569 | * v9fs_remove - helper function to remove files and directories |
536 | * @dir: directory inode that is being deleted | 570 | * @dir: directory inode that is being deleted |
537 | * @dentry: dentry that is being deleted | 571 | * @dentry: dentry that is being deleted |
@@ -558,7 +592,8 @@ static int v9fs_remove(struct inode *dir, struct dentry *dentry, int flags) | |||
558 | return retval; | 592 | return retval; |
559 | } | 593 | } |
560 | if (v9fs_proto_dotl(v9ses)) | 594 | if (v9fs_proto_dotl(v9ses)) |
561 | retval = p9_client_unlinkat(dfid, dentry->d_name.name, flags); | 595 | retval = p9_client_unlinkat(dfid, dentry->d_name.name, |
596 | v9fs_at_to_dotl_flags(flags)); | ||
562 | if (retval == -EOPNOTSUPP) { | 597 | if (retval == -EOPNOTSUPP) { |
563 | /* Try the one based on path */ | 598 | /* Try the one based on path */ |
564 | v9fid = v9fs_fid_clone(dentry); | 599 | v9fid = v9fs_fid_clone(dentry); |
@@ -645,13 +680,11 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir, | |||
645 | P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err); | 680 | P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err); |
646 | goto error; | 681 | goto error; |
647 | } | 682 | } |
648 | d_instantiate(dentry, inode); | ||
649 | err = v9fs_fid_add(dentry, fid); | 683 | err = v9fs_fid_add(dentry, fid); |
650 | if (err < 0) | 684 | if (err < 0) |
651 | goto error; | 685 | goto error; |
652 | 686 | d_instantiate(dentry, inode); | |
653 | return ofid; | 687 | return ofid; |
654 | |||
655 | error: | 688 | error: |
656 | if (ofid) | 689 | if (ofid) |
657 | p9_client_clunk(ofid); | 690 | p9_client_clunk(ofid); |
@@ -792,6 +825,7 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
792 | struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, | 825 | struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, |
793 | struct nameidata *nameidata) | 826 | struct nameidata *nameidata) |
794 | { | 827 | { |
828 | struct dentry *res; | ||
795 | struct super_block *sb; | 829 | struct super_block *sb; |
796 | struct v9fs_session_info *v9ses; | 830 | struct v9fs_session_info *v9ses; |
797 | struct p9_fid *dfid, *fid; | 831 | struct p9_fid *dfid, *fid; |
@@ -823,22 +857,35 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, | |||
823 | 857 | ||
824 | return ERR_PTR(result); | 858 | return ERR_PTR(result); |
825 | } | 859 | } |
826 | 860 | /* | |
827 | inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); | 861 | * Make sure we don't use a wrong inode due to parallel |
862 | * unlink. For cached mode create calls request for new | ||
863 | * inode. But with cache disabled, lookup should do this. | ||
864 | */ | ||
865 | if (v9ses->cache) | ||
866 | inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); | ||
867 | else | ||
868 | inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); | ||
828 | if (IS_ERR(inode)) { | 869 | if (IS_ERR(inode)) { |
829 | result = PTR_ERR(inode); | 870 | result = PTR_ERR(inode); |
830 | inode = NULL; | 871 | inode = NULL; |
831 | goto error; | 872 | goto error; |
832 | } | 873 | } |
833 | |||
834 | result = v9fs_fid_add(dentry, fid); | 874 | result = v9fs_fid_add(dentry, fid); |
835 | if (result < 0) | 875 | if (result < 0) |
836 | goto error_iput; | 876 | goto error_iput; |
837 | |||
838 | inst_out: | 877 | inst_out: |
839 | d_add(dentry, inode); | 878 | /* |
840 | return NULL; | 879 | * If we had a rename on the server and a parallel lookup |
841 | 880 | * for the new name, then make sure we instantiate with | |
881 | * the new name. ie look up for a/b, while on server somebody | ||
882 | * moved b under k and client parallely did a lookup for | ||
883 | * k/b. | ||
884 | */ | ||
885 | res = d_materialise_unique(dentry, inode); | ||
886 | if (!IS_ERR(res)) | ||
887 | return res; | ||
888 | result = PTR_ERR(res); | ||
842 | error_iput: | 889 | error_iput: |
843 | iput(inode); | 890 | iput(inode); |
844 | error: | 891 | error: |
@@ -1002,7 +1049,7 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
1002 | return PTR_ERR(st); | 1049 | return PTR_ERR(st); |
1003 | 1050 | ||
1004 | v9fs_stat2inode(st, dentry->d_inode, dentry->d_inode->i_sb); | 1051 | v9fs_stat2inode(st, dentry->d_inode, dentry->d_inode->i_sb); |
1005 | generic_fillattr(dentry->d_inode, stat); | 1052 | generic_fillattr(dentry->d_inode, stat); |
1006 | 1053 | ||
1007 | p9stat_free(st); | 1054 | p9stat_free(st); |
1008 | kfree(st); | 1055 | kfree(st); |
@@ -1086,6 +1133,7 @@ void | |||
1086 | v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode, | 1133 | v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode, |
1087 | struct super_block *sb) | 1134 | struct super_block *sb) |
1088 | { | 1135 | { |
1136 | mode_t mode; | ||
1089 | char ext[32]; | 1137 | char ext[32]; |
1090 | char tag_name[14]; | 1138 | char tag_name[14]; |
1091 | unsigned int i_nlink; | 1139 | unsigned int i_nlink; |
@@ -1121,31 +1169,9 @@ v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode, | |||
1121 | inode->i_nlink = i_nlink; | 1169 | inode->i_nlink = i_nlink; |
1122 | } | 1170 | } |
1123 | } | 1171 | } |
1124 | inode->i_mode = p9mode2unixmode(v9ses, stat->mode); | 1172 | mode = stat->mode & S_IALLUGO; |
1125 | if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode))) { | 1173 | mode |= inode->i_mode & ~S_IALLUGO; |
1126 | char type = 0; | 1174 | inode->i_mode = mode; |
1127 | int major = -1; | ||
1128 | int minor = -1; | ||
1129 | |||
1130 | strncpy(ext, stat->extension, sizeof(ext)); | ||
1131 | sscanf(ext, "%c %u %u", &type, &major, &minor); | ||
1132 | switch (type) { | ||
1133 | case 'c': | ||
1134 | inode->i_mode &= ~S_IFBLK; | ||
1135 | inode->i_mode |= S_IFCHR; | ||
1136 | break; | ||
1137 | case 'b': | ||
1138 | break; | ||
1139 | default: | ||
1140 | P9_DPRINTK(P9_DEBUG_ERROR, | ||
1141 | "Unknown special type %c %s\n", type, | ||
1142 | stat->extension); | ||
1143 | }; | ||
1144 | inode->i_rdev = MKDEV(major, minor); | ||
1145 | init_special_inode(inode, inode->i_mode, inode->i_rdev); | ||
1146 | } else | ||
1147 | inode->i_rdev = 0; | ||
1148 | |||
1149 | i_size_write(inode, stat->length); | 1175 | i_size_write(inode, stat->length); |
1150 | 1176 | ||
1151 | /* not real number of blocks, but 512 byte ones ... */ | 1177 | /* not real number of blocks, but 512 byte ones ... */ |
@@ -1411,6 +1437,8 @@ v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) | |||
1411 | 1437 | ||
1412 | int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode) | 1438 | int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode) |
1413 | { | 1439 | { |
1440 | int umode; | ||
1441 | dev_t rdev; | ||
1414 | loff_t i_size; | 1442 | loff_t i_size; |
1415 | struct p9_wstat *st; | 1443 | struct p9_wstat *st; |
1416 | struct v9fs_session_info *v9ses; | 1444 | struct v9fs_session_info *v9ses; |
@@ -1419,6 +1447,12 @@ int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode) | |||
1419 | st = p9_client_stat(fid); | 1447 | st = p9_client_stat(fid); |
1420 | if (IS_ERR(st)) | 1448 | if (IS_ERR(st)) |
1421 | return PTR_ERR(st); | 1449 | return PTR_ERR(st); |
1450 | /* | ||
1451 | * Don't update inode if the file type is different | ||
1452 | */ | ||
1453 | umode = p9mode2unixmode(v9ses, st, &rdev); | ||
1454 | if ((inode->i_mode & S_IFMT) != (umode & S_IFMT)) | ||
1455 | goto out; | ||
1422 | 1456 | ||
1423 | spin_lock(&inode->i_lock); | 1457 | spin_lock(&inode->i_lock); |
1424 | /* | 1458 | /* |
@@ -1430,6 +1464,7 @@ int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode) | |||
1430 | if (v9ses->cache) | 1464 | if (v9ses->cache) |
1431 | inode->i_size = i_size; | 1465 | inode->i_size = i_size; |
1432 | spin_unlock(&inode->i_lock); | 1466 | spin_unlock(&inode->i_lock); |
1467 | out: | ||
1433 | p9stat_free(st); | 1468 | p9stat_free(st); |
1434 | kfree(st); | 1469 | kfree(st); |
1435 | return 0; | 1470 | return 0; |
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index b6c8ed205192..aded79fcd5cf 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c | |||
@@ -153,7 +153,8 @@ static struct inode *v9fs_qid_iget_dotl(struct super_block *sb, | |||
153 | * later. | 153 | * later. |
154 | */ | 154 | */ |
155 | inode->i_ino = i_ino; | 155 | inode->i_ino = i_ino; |
156 | retval = v9fs_init_inode(v9ses, inode, st->st_mode); | 156 | retval = v9fs_init_inode(v9ses, inode, |
157 | st->st_mode, new_decode_dev(st->st_rdev)); | ||
157 | if (retval) | 158 | if (retval) |
158 | goto error; | 159 | goto error; |
159 | 160 | ||
@@ -190,6 +191,58 @@ v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid, | |||
190 | return inode; | 191 | return inode; |
191 | } | 192 | } |
192 | 193 | ||
194 | struct dotl_openflag_map { | ||
195 | int open_flag; | ||
196 | int dotl_flag; | ||
197 | }; | ||
198 | |||
199 | static int v9fs_mapped_dotl_flags(int flags) | ||
200 | { | ||
201 | int i; | ||
202 | int rflags = 0; | ||
203 | struct dotl_openflag_map dotl_oflag_map[] = { | ||
204 | { O_CREAT, P9_DOTL_CREATE }, | ||
205 | { O_EXCL, P9_DOTL_EXCL }, | ||
206 | { O_NOCTTY, P9_DOTL_NOCTTY }, | ||
207 | { O_TRUNC, P9_DOTL_TRUNC }, | ||
208 | { O_APPEND, P9_DOTL_APPEND }, | ||
209 | { O_NONBLOCK, P9_DOTL_NONBLOCK }, | ||
210 | { O_DSYNC, P9_DOTL_DSYNC }, | ||
211 | { FASYNC, P9_DOTL_FASYNC }, | ||
212 | { O_DIRECT, P9_DOTL_DIRECT }, | ||
213 | { O_LARGEFILE, P9_DOTL_LARGEFILE }, | ||
214 | { O_DIRECTORY, P9_DOTL_DIRECTORY }, | ||
215 | { O_NOFOLLOW, P9_DOTL_NOFOLLOW }, | ||
216 | { O_NOATIME, P9_DOTL_NOATIME }, | ||
217 | { O_CLOEXEC, P9_DOTL_CLOEXEC }, | ||
218 | { O_SYNC, P9_DOTL_SYNC}, | ||
219 | }; | ||
220 | for (i = 0; i < ARRAY_SIZE(dotl_oflag_map); i++) { | ||
221 | if (flags & dotl_oflag_map[i].open_flag) | ||
222 | rflags |= dotl_oflag_map[i].dotl_flag; | ||
223 | } | ||
224 | return rflags; | ||
225 | } | ||
226 | |||
227 | /** | ||
228 | * v9fs_open_to_dotl_flags- convert Linux specific open flags to | ||
229 | * plan 9 open flag. | ||
230 | * @flags: flags to convert | ||
231 | */ | ||
232 | int v9fs_open_to_dotl_flags(int flags) | ||
233 | { | ||
234 | int rflags = 0; | ||
235 | |||
236 | /* | ||
237 | * We have same bits for P9_DOTL_READONLY, P9_DOTL_WRONLY | ||
238 | * and P9_DOTL_NOACCESS | ||
239 | */ | ||
240 | rflags |= flags & O_ACCMODE; | ||
241 | rflags |= v9fs_mapped_dotl_flags(flags); | ||
242 | |||
243 | return rflags; | ||
244 | } | ||
245 | |||
193 | /** | 246 | /** |
194 | * v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol. | 247 | * v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol. |
195 | * @dir: directory inode that is being created | 248 | * @dir: directory inode that is being created |
@@ -258,7 +311,8 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode, | |||
258 | "Failed to get acl values in creat %d\n", err); | 311 | "Failed to get acl values in creat %d\n", err); |
259 | goto error; | 312 | goto error; |
260 | } | 313 | } |
261 | err = p9_client_create_dotl(ofid, name, flags, mode, gid, &qid); | 314 | err = p9_client_create_dotl(ofid, name, v9fs_open_to_dotl_flags(flags), |
315 | mode, gid, &qid); | ||
262 | if (err < 0) { | 316 | if (err < 0) { |
263 | P9_DPRINTK(P9_DEBUG_VFS, | 317 | P9_DPRINTK(P9_DEBUG_VFS, |
264 | "p9_client_open_dotl failed in creat %d\n", | 318 | "p9_client_open_dotl failed in creat %d\n", |
@@ -281,10 +335,10 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode, | |||
281 | P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err); | 335 | P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err); |
282 | goto error; | 336 | goto error; |
283 | } | 337 | } |
284 | d_instantiate(dentry, inode); | ||
285 | err = v9fs_fid_add(dentry, fid); | 338 | err = v9fs_fid_add(dentry, fid); |
286 | if (err < 0) | 339 | if (err < 0) |
287 | goto error; | 340 | goto error; |
341 | d_instantiate(dentry, inode); | ||
288 | 342 | ||
289 | /* Now set the ACL based on the default value */ | 343 | /* Now set the ACL based on the default value */ |
290 | v9fs_set_create_acl(dentry, &dacl, &pacl); | 344 | v9fs_set_create_acl(dentry, &dacl, &pacl); |
@@ -403,10 +457,10 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir, | |||
403 | err); | 457 | err); |
404 | goto error; | 458 | goto error; |
405 | } | 459 | } |
406 | d_instantiate(dentry, inode); | ||
407 | err = v9fs_fid_add(dentry, fid); | 460 | err = v9fs_fid_add(dentry, fid); |
408 | if (err < 0) | 461 | if (err < 0) |
409 | goto error; | 462 | goto error; |
463 | d_instantiate(dentry, inode); | ||
410 | fid = NULL; | 464 | fid = NULL; |
411 | } else { | 465 | } else { |
412 | /* | 466 | /* |
@@ -414,7 +468,7 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir, | |||
414 | * inode with stat. We need to get an inode | 468 | * inode with stat. We need to get an inode |
415 | * so that we can set the acl with dentry | 469 | * so that we can set the acl with dentry |
416 | */ | 470 | */ |
417 | inode = v9fs_get_inode(dir->i_sb, mode); | 471 | inode = v9fs_get_inode(dir->i_sb, mode, 0); |
418 | if (IS_ERR(inode)) { | 472 | if (IS_ERR(inode)) { |
419 | err = PTR_ERR(inode); | 473 | err = PTR_ERR(inode); |
420 | goto error; | 474 | goto error; |
@@ -540,6 +594,7 @@ int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr) | |||
540 | void | 594 | void |
541 | v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode) | 595 | v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode) |
542 | { | 596 | { |
597 | mode_t mode; | ||
543 | struct v9fs_inode *v9inode = V9FS_I(inode); | 598 | struct v9fs_inode *v9inode = V9FS_I(inode); |
544 | 599 | ||
545 | if ((stat->st_result_mask & P9_STATS_BASIC) == P9_STATS_BASIC) { | 600 | if ((stat->st_result_mask & P9_STATS_BASIC) == P9_STATS_BASIC) { |
@@ -552,11 +607,10 @@ v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode) | |||
552 | inode->i_uid = stat->st_uid; | 607 | inode->i_uid = stat->st_uid; |
553 | inode->i_gid = stat->st_gid; | 608 | inode->i_gid = stat->st_gid; |
554 | inode->i_nlink = stat->st_nlink; | 609 | inode->i_nlink = stat->st_nlink; |
555 | inode->i_mode = stat->st_mode; | ||
556 | inode->i_rdev = new_decode_dev(stat->st_rdev); | ||
557 | 610 | ||
558 | if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode))) | 611 | mode = stat->st_mode & S_IALLUGO; |
559 | init_special_inode(inode, inode->i_mode, inode->i_rdev); | 612 | mode |= inode->i_mode & ~S_IALLUGO; |
613 | inode->i_mode = mode; | ||
560 | 614 | ||
561 | i_size_write(inode, stat->st_size); | 615 | i_size_write(inode, stat->st_size); |
562 | inode->i_blocks = stat->st_blocks; | 616 | inode->i_blocks = stat->st_blocks; |
@@ -657,14 +711,14 @@ v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry, | |||
657 | err); | 711 | err); |
658 | goto error; | 712 | goto error; |
659 | } | 713 | } |
660 | d_instantiate(dentry, inode); | ||
661 | err = v9fs_fid_add(dentry, fid); | 714 | err = v9fs_fid_add(dentry, fid); |
662 | if (err < 0) | 715 | if (err < 0) |
663 | goto error; | 716 | goto error; |
717 | d_instantiate(dentry, inode); | ||
664 | fid = NULL; | 718 | fid = NULL; |
665 | } else { | 719 | } else { |
666 | /* Not in cached mode. No need to populate inode with stat */ | 720 | /* Not in cached mode. No need to populate inode with stat */ |
667 | inode = v9fs_get_inode(dir->i_sb, S_IFLNK); | 721 | inode = v9fs_get_inode(dir->i_sb, S_IFLNK, 0); |
668 | if (IS_ERR(inode)) { | 722 | if (IS_ERR(inode)) { |
669 | err = PTR_ERR(inode); | 723 | err = PTR_ERR(inode); |
670 | goto error; | 724 | goto error; |
@@ -810,17 +864,17 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode, | |||
810 | err); | 864 | err); |
811 | goto error; | 865 | goto error; |
812 | } | 866 | } |
813 | d_instantiate(dentry, inode); | ||
814 | err = v9fs_fid_add(dentry, fid); | 867 | err = v9fs_fid_add(dentry, fid); |
815 | if (err < 0) | 868 | if (err < 0) |
816 | goto error; | 869 | goto error; |
870 | d_instantiate(dentry, inode); | ||
817 | fid = NULL; | 871 | fid = NULL; |
818 | } else { | 872 | } else { |
819 | /* | 873 | /* |
820 | * Not in cached mode. No need to populate inode with stat. | 874 | * Not in cached mode. No need to populate inode with stat. |
821 | * socket syscall returns a fd, so we need instantiate | 875 | * socket syscall returns a fd, so we need instantiate |
822 | */ | 876 | */ |
823 | inode = v9fs_get_inode(dir->i_sb, mode); | 877 | inode = v9fs_get_inode(dir->i_sb, mode, rdev); |
824 | if (IS_ERR(inode)) { | 878 | if (IS_ERR(inode)) { |
825 | err = PTR_ERR(inode); | 879 | err = PTR_ERR(inode); |
826 | goto error; | 880 | goto error; |
@@ -886,6 +940,11 @@ int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode) | |||
886 | st = p9_client_getattr_dotl(fid, P9_STATS_ALL); | 940 | st = p9_client_getattr_dotl(fid, P9_STATS_ALL); |
887 | if (IS_ERR(st)) | 941 | if (IS_ERR(st)) |
888 | return PTR_ERR(st); | 942 | return PTR_ERR(st); |
943 | /* | ||
944 | * Don't update inode if the file type is different | ||
945 | */ | ||
946 | if ((inode->i_mode & S_IFMT) != (st->st_mode & S_IFMT)) | ||
947 | goto out; | ||
889 | 948 | ||
890 | spin_lock(&inode->i_lock); | 949 | spin_lock(&inode->i_lock); |
891 | /* | 950 | /* |
@@ -897,6 +956,7 @@ int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode) | |||
897 | if (v9ses->cache) | 956 | if (v9ses->cache) |
898 | inode->i_size = i_size; | 957 | inode->i_size = i_size; |
899 | spin_unlock(&inode->i_lock); | 958 | spin_unlock(&inode->i_lock); |
959 | out: | ||
900 | kfree(st); | 960 | kfree(st); |
901 | return 0; | 961 | return 0; |
902 | } | 962 | } |
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index feef6cdc1fd2..c70251d47ed1 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c | |||
@@ -149,7 +149,7 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags, | |||
149 | else | 149 | else |
150 | sb->s_d_op = &v9fs_dentry_operations; | 150 | sb->s_d_op = &v9fs_dentry_operations; |
151 | 151 | ||
152 | inode = v9fs_get_inode(sb, S_IFDIR | mode); | 152 | inode = v9fs_get_inode(sb, S_IFDIR | mode, 0); |
153 | if (IS_ERR(inode)) { | 153 | if (IS_ERR(inode)) { |
154 | retval = PTR_ERR(inode); | 154 | retval = PTR_ERR(inode); |
155 | goto release_sb; | 155 | goto release_sb; |
diff --git a/fs/block_dev.c b/fs/block_dev.c index ff77262e887c..95f786ec7f08 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -1429,6 +1429,11 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part) | |||
1429 | WARN_ON_ONCE(bdev->bd_holders); | 1429 | WARN_ON_ONCE(bdev->bd_holders); |
1430 | sync_blockdev(bdev); | 1430 | sync_blockdev(bdev); |
1431 | kill_bdev(bdev); | 1431 | kill_bdev(bdev); |
1432 | /* ->release can cause the old bdi to disappear, | ||
1433 | * so must switch it out first | ||
1434 | */ | ||
1435 | bdev_inode_switch_bdi(bdev->bd_inode, | ||
1436 | &default_backing_dev_info); | ||
1432 | } | 1437 | } |
1433 | if (bdev->bd_contains == bdev) { | 1438 | if (bdev->bd_contains == bdev) { |
1434 | if (disk->fops->release) | 1439 | if (disk->fops->release) |
@@ -1442,8 +1447,6 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part) | |||
1442 | disk_put_part(bdev->bd_part); | 1447 | disk_put_part(bdev->bd_part); |
1443 | bdev->bd_part = NULL; | 1448 | bdev->bd_part = NULL; |
1444 | bdev->bd_disk = NULL; | 1449 | bdev->bd_disk = NULL; |
1445 | bdev_inode_switch_bdi(bdev->bd_inode, | ||
1446 | &default_backing_dev_info); | ||
1447 | if (bdev != bdev->bd_contains) | 1450 | if (bdev != bdev->bd_contains) |
1448 | victim = bdev->bd_contains; | 1451 | victim = bdev->bd_contains; |
1449 | bdev->bd_contains = NULL; | 1452 | bdev->bd_contains = NULL; |
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h index 502b9e988679..d9f99a16edd6 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h | |||
@@ -176,7 +176,11 @@ static inline u64 btrfs_ino(struct inode *inode) | |||
176 | { | 176 | { |
177 | u64 ino = BTRFS_I(inode)->location.objectid; | 177 | u64 ino = BTRFS_I(inode)->location.objectid; |
178 | 178 | ||
179 | if (ino <= BTRFS_FIRST_FREE_OBJECTID) | 179 | /* |
180 | * !ino: btree_inode | ||
181 | * type == BTRFS_ROOT_ITEM_KEY: subvol dir | ||
182 | */ | ||
183 | if (!ino || BTRFS_I(inode)->location.type == BTRFS_ROOT_ITEM_KEY) | ||
180 | ino = inode->i_ino; | 184 | ino = inode->i_ino; |
181 | return ino; | 185 | return ino; |
182 | } | 186 | } |
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index b910694f61ed..a1cb7821becd 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c | |||
@@ -183,8 +183,10 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root, | |||
183 | * read from the commit root and sidestep a nasty deadlock | 183 | * read from the commit root and sidestep a nasty deadlock |
184 | * between reading the free space cache and updating the csum tree. | 184 | * between reading the free space cache and updating the csum tree. |
185 | */ | 185 | */ |
186 | if (btrfs_is_free_space_inode(root, inode)) | 186 | if (btrfs_is_free_space_inode(root, inode)) { |
187 | path->search_commit_root = 1; | 187 | path->search_commit_root = 1; |
188 | path->skip_locking = 1; | ||
189 | } | ||
188 | 190 | ||
189 | disk_bytenr = (u64)bio->bi_sector << 9; | 191 | disk_bytenr = (u64)bio->bi_sector << 9; |
190 | if (dio) | 192 | if (dio) |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index e7872e485f13..3c3abff731a7 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -1075,12 +1075,6 @@ static noinline int prepare_pages(struct btrfs_root *root, struct file *file, | |||
1075 | start_pos = pos & ~((u64)root->sectorsize - 1); | 1075 | start_pos = pos & ~((u64)root->sectorsize - 1); |
1076 | last_pos = ((u64)index + num_pages) << PAGE_CACHE_SHIFT; | 1076 | last_pos = ((u64)index + num_pages) << PAGE_CACHE_SHIFT; |
1077 | 1077 | ||
1078 | if (start_pos > inode->i_size) { | ||
1079 | err = btrfs_cont_expand(inode, i_size_read(inode), start_pos); | ||
1080 | if (err) | ||
1081 | return err; | ||
1082 | } | ||
1083 | |||
1084 | again: | 1078 | again: |
1085 | for (i = 0; i < num_pages; i++) { | 1079 | for (i = 0; i < num_pages; i++) { |
1086 | pages[i] = find_or_create_page(inode->i_mapping, index + i, | 1080 | pages[i] = find_or_create_page(inode->i_mapping, index + i, |
@@ -1338,6 +1332,7 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
1338 | struct inode *inode = fdentry(file)->d_inode; | 1332 | struct inode *inode = fdentry(file)->d_inode; |
1339 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1333 | struct btrfs_root *root = BTRFS_I(inode)->root; |
1340 | loff_t *ppos = &iocb->ki_pos; | 1334 | loff_t *ppos = &iocb->ki_pos; |
1335 | u64 start_pos; | ||
1341 | ssize_t num_written = 0; | 1336 | ssize_t num_written = 0; |
1342 | ssize_t err = 0; | 1337 | ssize_t err = 0; |
1343 | size_t count, ocount; | 1338 | size_t count, ocount; |
@@ -1386,6 +1381,15 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
1386 | file_update_time(file); | 1381 | file_update_time(file); |
1387 | BTRFS_I(inode)->sequence++; | 1382 | BTRFS_I(inode)->sequence++; |
1388 | 1383 | ||
1384 | start_pos = round_down(pos, root->sectorsize); | ||
1385 | if (start_pos > i_size_read(inode)) { | ||
1386 | err = btrfs_cont_expand(inode, i_size_read(inode), start_pos); | ||
1387 | if (err) { | ||
1388 | mutex_unlock(&inode->i_mutex); | ||
1389 | goto out; | ||
1390 | } | ||
1391 | } | ||
1392 | |||
1389 | if (unlikely(file->f_flags & O_DIRECT)) { | 1393 | if (unlikely(file->f_flags & O_DIRECT)) { |
1390 | num_written = __btrfs_direct_write(iocb, iov, nr_segs, | 1394 | num_written = __btrfs_direct_write(iocb, iov, nr_segs, |
1391 | pos, ppos, count, ocount); | 1395 | pos, ppos, count, ocount); |
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index 6a265b9f85f2..41ac927401d0 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
@@ -190,9 +190,11 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root, | |||
190 | struct btrfs_path *path, | 190 | struct btrfs_path *path, |
191 | struct inode *inode) | 191 | struct inode *inode) |
192 | { | 192 | { |
193 | struct btrfs_block_rsv *rsv; | ||
193 | loff_t oldsize; | 194 | loff_t oldsize; |
194 | int ret = 0; | 195 | int ret = 0; |
195 | 196 | ||
197 | rsv = trans->block_rsv; | ||
196 | trans->block_rsv = root->orphan_block_rsv; | 198 | trans->block_rsv = root->orphan_block_rsv; |
197 | ret = btrfs_block_rsv_check(trans, root, | 199 | ret = btrfs_block_rsv_check(trans, root, |
198 | root->orphan_block_rsv, | 200 | root->orphan_block_rsv, |
@@ -210,6 +212,8 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root, | |||
210 | */ | 212 | */ |
211 | ret = btrfs_truncate_inode_items(trans, root, inode, | 213 | ret = btrfs_truncate_inode_items(trans, root, inode, |
212 | 0, BTRFS_EXTENT_DATA_KEY); | 214 | 0, BTRFS_EXTENT_DATA_KEY); |
215 | |||
216 | trans->block_rsv = rsv; | ||
213 | if (ret) { | 217 | if (ret) { |
214 | WARN_ON(1); | 218 | WARN_ON(1); |
215 | return ret; | 219 | return ret; |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 0ccc7438ad34..4d14de6d121b 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -1786,7 +1786,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
1786 | &ordered_extent->list); | 1786 | &ordered_extent->list); |
1787 | 1787 | ||
1788 | ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent); | 1788 | ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent); |
1789 | if (!ret) { | 1789 | if (!ret || !test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) { |
1790 | ret = btrfs_update_inode(trans, root, inode); | 1790 | ret = btrfs_update_inode(trans, root, inode); |
1791 | BUG_ON(ret); | 1791 | BUG_ON(ret); |
1792 | } | 1792 | } |
@@ -3510,15 +3510,19 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size) | |||
3510 | err = btrfs_drop_extents(trans, inode, cur_offset, | 3510 | err = btrfs_drop_extents(trans, inode, cur_offset, |
3511 | cur_offset + hole_size, | 3511 | cur_offset + hole_size, |
3512 | &hint_byte, 1); | 3512 | &hint_byte, 1); |
3513 | if (err) | 3513 | if (err) { |
3514 | btrfs_end_transaction(trans, root); | ||
3514 | break; | 3515 | break; |
3516 | } | ||
3515 | 3517 | ||
3516 | err = btrfs_insert_file_extent(trans, root, | 3518 | err = btrfs_insert_file_extent(trans, root, |
3517 | btrfs_ino(inode), cur_offset, 0, | 3519 | btrfs_ino(inode), cur_offset, 0, |
3518 | 0, hole_size, 0, hole_size, | 3520 | 0, hole_size, 0, hole_size, |
3519 | 0, 0, 0); | 3521 | 0, 0, 0); |
3520 | if (err) | 3522 | if (err) { |
3523 | btrfs_end_transaction(trans, root); | ||
3521 | break; | 3524 | break; |
3525 | } | ||
3522 | 3526 | ||
3523 | btrfs_drop_extent_cache(inode, hole_start, | 3527 | btrfs_drop_extent_cache(inode, hole_start, |
3524 | last_byte - 1, 0); | 3528 | last_byte - 1, 0); |
@@ -3952,7 +3956,6 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, | |||
3952 | struct btrfs_root *root, int *new) | 3956 | struct btrfs_root *root, int *new) |
3953 | { | 3957 | { |
3954 | struct inode *inode; | 3958 | struct inode *inode; |
3955 | int bad_inode = 0; | ||
3956 | 3959 | ||
3957 | inode = btrfs_iget_locked(s, location->objectid, root); | 3960 | inode = btrfs_iget_locked(s, location->objectid, root); |
3958 | if (!inode) | 3961 | if (!inode) |
@@ -3968,15 +3971,12 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, | |||
3968 | if (new) | 3971 | if (new) |
3969 | *new = 1; | 3972 | *new = 1; |
3970 | } else { | 3973 | } else { |
3971 | bad_inode = 1; | 3974 | unlock_new_inode(inode); |
3975 | iput(inode); | ||
3976 | inode = ERR_PTR(-ESTALE); | ||
3972 | } | 3977 | } |
3973 | } | 3978 | } |
3974 | 3979 | ||
3975 | if (bad_inode) { | ||
3976 | iput(inode); | ||
3977 | inode = ERR_PTR(-ESTALE); | ||
3978 | } | ||
3979 | |||
3980 | return inode; | 3980 | return inode; |
3981 | } | 3981 | } |
3982 | 3982 | ||
@@ -5823,7 +5823,7 @@ again: | |||
5823 | 5823 | ||
5824 | add_pending_csums(trans, inode, ordered->file_offset, &ordered->list); | 5824 | add_pending_csums(trans, inode, ordered->file_offset, &ordered->list); |
5825 | ret = btrfs_ordered_update_i_size(inode, 0, ordered); | 5825 | ret = btrfs_ordered_update_i_size(inode, 0, ordered); |
5826 | if (!ret) | 5826 | if (!ret || !test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags)) |
5827 | btrfs_update_inode(trans, root, inode); | 5827 | btrfs_update_inode(trans, root, inode); |
5828 | ret = 0; | 5828 | ret = 0; |
5829 | out_unlock: | 5829 | out_unlock: |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 970977aab224..3351b1b24574 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -2220,6 +2220,12 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
2220 | !IS_ALIGNED(destoff, bs)) | 2220 | !IS_ALIGNED(destoff, bs)) |
2221 | goto out_unlock; | 2221 | goto out_unlock; |
2222 | 2222 | ||
2223 | if (destoff > inode->i_size) { | ||
2224 | ret = btrfs_cont_expand(inode, inode->i_size, destoff); | ||
2225 | if (ret) | ||
2226 | goto out_unlock; | ||
2227 | } | ||
2228 | |||
2223 | /* do any pending delalloc/csum calc on src, one way or | 2229 | /* do any pending delalloc/csum calc on src, one way or |
2224 | another, and lock file content */ | 2230 | another, and lock file content */ |
2225 | while (1) { | 2231 | while (1) { |
@@ -2325,14 +2331,21 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
2325 | 2331 | ||
2326 | if (type == BTRFS_FILE_EXTENT_REG || | 2332 | if (type == BTRFS_FILE_EXTENT_REG || |
2327 | type == BTRFS_FILE_EXTENT_PREALLOC) { | 2333 | type == BTRFS_FILE_EXTENT_PREALLOC) { |
2334 | /* | ||
2335 | * a | --- range to clone ---| b | ||
2336 | * | ------------- extent ------------- | | ||
2337 | */ | ||
2338 | |||
2339 | /* substract range b */ | ||
2340 | if (key.offset + datal > off + len) | ||
2341 | datal = off + len - key.offset; | ||
2342 | |||
2343 | /* substract range a */ | ||
2328 | if (off > key.offset) { | 2344 | if (off > key.offset) { |
2329 | datao += off - key.offset; | 2345 | datao += off - key.offset; |
2330 | datal -= off - key.offset; | 2346 | datal -= off - key.offset; |
2331 | } | 2347 | } |
2332 | 2348 | ||
2333 | if (key.offset + datal > off + len) | ||
2334 | datal = off + len - key.offset; | ||
2335 | |||
2336 | ret = btrfs_drop_extents(trans, inode, | 2349 | ret = btrfs_drop_extents(trans, inode, |
2337 | new_key.offset, | 2350 | new_key.offset, |
2338 | new_key.offset + datal, | 2351 | new_key.offset + datal, |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 7dc36fab4afc..e24b7964a155 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -884,6 +884,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
884 | struct btrfs_root *tree_root = fs_info->tree_root; | 884 | struct btrfs_root *tree_root = fs_info->tree_root; |
885 | struct btrfs_root *root = pending->root; | 885 | struct btrfs_root *root = pending->root; |
886 | struct btrfs_root *parent_root; | 886 | struct btrfs_root *parent_root; |
887 | struct btrfs_block_rsv *rsv; | ||
887 | struct inode *parent_inode; | 888 | struct inode *parent_inode; |
888 | struct dentry *parent; | 889 | struct dentry *parent; |
889 | struct dentry *dentry; | 890 | struct dentry *dentry; |
@@ -895,6 +896,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
895 | u64 objectid; | 896 | u64 objectid; |
896 | u64 root_flags; | 897 | u64 root_flags; |
897 | 898 | ||
899 | rsv = trans->block_rsv; | ||
900 | |||
898 | new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS); | 901 | new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS); |
899 | if (!new_root_item) { | 902 | if (!new_root_item) { |
900 | pending->error = -ENOMEM; | 903 | pending->error = -ENOMEM; |
@@ -1002,6 +1005,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
1002 | btrfs_orphan_post_snapshot(trans, pending); | 1005 | btrfs_orphan_post_snapshot(trans, pending); |
1003 | fail: | 1006 | fail: |
1004 | kfree(new_root_item); | 1007 | kfree(new_root_item); |
1008 | trans->block_rsv = rsv; | ||
1005 | btrfs_block_rsv_release(root, &pending->block_rsv, (u64)-1); | 1009 | btrfs_block_rsv_release(root, &pending->block_rsv, (u64)-1); |
1006 | return 0; | 1010 | return 0; |
1007 | } | 1011 | } |
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c index d733b9cfea34..69565e5fc6a0 100644 --- a/fs/btrfs/xattr.c +++ b/fs/btrfs/xattr.c | |||
@@ -116,6 +116,12 @@ static int do_setxattr(struct btrfs_trans_handle *trans, | |||
116 | if (ret) | 116 | if (ret) |
117 | goto out; | 117 | goto out; |
118 | btrfs_release_path(path); | 118 | btrfs_release_path(path); |
119 | |||
120 | /* | ||
121 | * remove the attribute | ||
122 | */ | ||
123 | if (!value) | ||
124 | goto out; | ||
119 | } | 125 | } |
120 | 126 | ||
121 | again: | 127 | again: |
@@ -158,6 +164,9 @@ out: | |||
158 | return ret; | 164 | return ret; |
159 | } | 165 | } |
160 | 166 | ||
167 | /* | ||
168 | * @value: "" makes the attribute to empty, NULL removes it | ||
169 | */ | ||
161 | int __btrfs_setxattr(struct btrfs_trans_handle *trans, | 170 | int __btrfs_setxattr(struct btrfs_trans_handle *trans, |
162 | struct inode *inode, const char *name, | 171 | struct inode *inode, const char *name, |
163 | const void *value, size_t size, int flags) | 172 | const void *value, size_t size, int flags) |
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index fee028b5332e..86c59e16ba74 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -1595,7 +1595,7 @@ static int set_request_path_attr(struct inode *rinode, struct dentry *rdentry, | |||
1595 | r = build_dentry_path(rdentry, ppath, pathlen, ino, freepath); | 1595 | r = build_dentry_path(rdentry, ppath, pathlen, ino, freepath); |
1596 | dout(" dentry %p %llx/%.*s\n", rdentry, *ino, *pathlen, | 1596 | dout(" dentry %p %llx/%.*s\n", rdentry, *ino, *pathlen, |
1597 | *ppath); | 1597 | *ppath); |
1598 | } else if (rpath) { | 1598 | } else if (rpath || rino) { |
1599 | *ino = rino; | 1599 | *ino = rino; |
1600 | *ppath = rpath; | 1600 | *ppath = rpath; |
1601 | *pathlen = strlen(rpath); | 1601 | *pathlen = strlen(rpath); |
diff --git a/fs/ceph/super.c b/fs/ceph/super.c index d47c5ec7fb1f..88bacaf385d9 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c | |||
@@ -813,8 +813,8 @@ static struct dentry *ceph_mount(struct file_system_type *fs_type, | |||
813 | fsc = create_fs_client(fsopt, opt); | 813 | fsc = create_fs_client(fsopt, opt); |
814 | if (IS_ERR(fsc)) { | 814 | if (IS_ERR(fsc)) { |
815 | res = ERR_CAST(fsc); | 815 | res = ERR_CAST(fsc); |
816 | kfree(fsopt); | 816 | destroy_mount_options(fsopt); |
817 | kfree(opt); | 817 | ceph_destroy_options(opt); |
818 | goto out_final; | 818 | goto out_final; |
819 | } | 819 | } |
820 | 820 | ||
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index e717dfd2f2b4..b7d7bd0f066e 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -175,6 +175,7 @@ struct mpage_da_data { | |||
175 | */ | 175 | */ |
176 | #define EXT4_IO_END_UNWRITTEN 0x0001 | 176 | #define EXT4_IO_END_UNWRITTEN 0x0001 |
177 | #define EXT4_IO_END_ERROR 0x0002 | 177 | #define EXT4_IO_END_ERROR 0x0002 |
178 | #define EXT4_IO_END_QUEUED 0x0004 | ||
178 | 179 | ||
179 | struct ext4_io_page { | 180 | struct ext4_io_page { |
180 | struct page *p_page; | 181 | struct page *p_page; |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index c4da98a959ae..18d2558b7624 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -121,9 +121,6 @@ void ext4_evict_inode(struct inode *inode) | |||
121 | 121 | ||
122 | trace_ext4_evict_inode(inode); | 122 | trace_ext4_evict_inode(inode); |
123 | 123 | ||
124 | mutex_lock(&inode->i_mutex); | ||
125 | ext4_flush_completed_IO(inode); | ||
126 | mutex_unlock(&inode->i_mutex); | ||
127 | ext4_ioend_wait(inode); | 124 | ext4_ioend_wait(inode); |
128 | 125 | ||
129 | if (inode->i_nlink) { | 126 | if (inode->i_nlink) { |
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index 78839af7ce29..92f38ee13f8a 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c | |||
@@ -142,7 +142,23 @@ static void ext4_end_io_work(struct work_struct *work) | |||
142 | unsigned long flags; | 142 | unsigned long flags; |
143 | int ret; | 143 | int ret; |
144 | 144 | ||
145 | mutex_lock(&inode->i_mutex); | 145 | if (!mutex_trylock(&inode->i_mutex)) { |
146 | /* | ||
147 | * Requeue the work instead of waiting so that the work | ||
148 | * items queued after this can be processed. | ||
149 | */ | ||
150 | queue_work(EXT4_SB(inode->i_sb)->dio_unwritten_wq, &io->work); | ||
151 | /* | ||
152 | * To prevent the ext4-dio-unwritten thread from keeping | ||
153 | * requeueing end_io requests and occupying cpu for too long, | ||
154 | * yield the cpu if it sees an end_io request that has already | ||
155 | * been requeued. | ||
156 | */ | ||
157 | if (io->flag & EXT4_IO_END_QUEUED) | ||
158 | yield(); | ||
159 | io->flag |= EXT4_IO_END_QUEUED; | ||
160 | return; | ||
161 | } | ||
146 | ret = ext4_end_io_nolock(io); | 162 | ret = ext4_end_io_nolock(io); |
147 | if (ret < 0) { | 163 | if (ret < 0) { |
148 | mutex_unlock(&inode->i_mutex); | 164 | mutex_unlock(&inode->i_mutex); |
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 168a80f7f12b..5cb8614508c3 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
@@ -258,10 +258,14 @@ void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget, | |||
258 | forget->forget_one.nlookup = nlookup; | 258 | forget->forget_one.nlookup = nlookup; |
259 | 259 | ||
260 | spin_lock(&fc->lock); | 260 | spin_lock(&fc->lock); |
261 | fc->forget_list_tail->next = forget; | 261 | if (fc->connected) { |
262 | fc->forget_list_tail = forget; | 262 | fc->forget_list_tail->next = forget; |
263 | wake_up(&fc->waitq); | 263 | fc->forget_list_tail = forget; |
264 | kill_fasync(&fc->fasync, SIGIO, POLL_IN); | 264 | wake_up(&fc->waitq); |
265 | kill_fasync(&fc->fasync, SIGIO, POLL_IN); | ||
266 | } else { | ||
267 | kfree(forget); | ||
268 | } | ||
265 | spin_unlock(&fc->lock); | 269 | spin_unlock(&fc->lock); |
266 | } | 270 | } |
267 | 271 | ||
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 12b502929da9..add96f6ffda5 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -812,6 +812,9 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) | |||
812 | if (arg->minor >= 17) { | 812 | if (arg->minor >= 17) { |
813 | if (!(arg->flags & FUSE_FLOCK_LOCKS)) | 813 | if (!(arg->flags & FUSE_FLOCK_LOCKS)) |
814 | fc->no_flock = 1; | 814 | fc->no_flock = 1; |
815 | } else { | ||
816 | if (!(arg->flags & FUSE_POSIX_LOCKS)) | ||
817 | fc->no_flock = 1; | ||
815 | } | 818 | } |
816 | if (arg->flags & FUSE_ATOMIC_O_TRUNC) | 819 | if (arg->flags & FUSE_ATOMIC_O_TRUNC) |
817 | fc->atomic_o_trunc = 1; | 820 | fc->atomic_o_trunc = 1; |
diff --git a/fs/namei.c b/fs/namei.c index 2826db35dc25..b52bc685465f 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -727,25 +727,22 @@ static int follow_automount(struct path *path, unsigned flags, | |||
727 | if ((flags & LOOKUP_NO_AUTOMOUNT) && !(flags & LOOKUP_PARENT)) | 727 | if ((flags & LOOKUP_NO_AUTOMOUNT) && !(flags & LOOKUP_PARENT)) |
728 | return -EISDIR; /* we actually want to stop here */ | 728 | return -EISDIR; /* we actually want to stop here */ |
729 | 729 | ||
730 | /* | 730 | /* We don't want to mount if someone's just doing a stat - |
731 | * We don't want to mount if someone's just doing a stat and they've | 731 | * unless they're stat'ing a directory and appended a '/' to |
732 | * set AT_SYMLINK_NOFOLLOW - unless they're stat'ing a directory and | 732 | * the name. |
733 | * appended a '/' to the name. | 733 | * |
734 | * We do, however, want to mount if someone wants to open or | ||
735 | * create a file of any type under the mountpoint, wants to | ||
736 | * traverse through the mountpoint or wants to open the | ||
737 | * mounted directory. Also, autofs may mark negative dentries | ||
738 | * as being automount points. These will need the attentions | ||
739 | * of the daemon to instantiate them before they can be used. | ||
734 | */ | 740 | */ |
735 | if (!(flags & LOOKUP_FOLLOW)) { | 741 | if (!(flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY | |
736 | /* We do, however, want to mount if someone wants to open or | 742 | LOOKUP_OPEN | LOOKUP_CREATE)) && |
737 | * create a file of any type under the mountpoint, wants to | 743 | path->dentry->d_inode) |
738 | * traverse through the mountpoint or wants to open the mounted | 744 | return -EISDIR; |
739 | * directory. | 745 | |
740 | * Also, autofs may mark negative dentries as being automount | ||
741 | * points. These will need the attentions of the daemon to | ||
742 | * instantiate them before they can be used. | ||
743 | */ | ||
744 | if (!(flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY | | ||
745 | LOOKUP_OPEN | LOOKUP_CREATE)) && | ||
746 | path->dentry->d_inode) | ||
747 | return -EISDIR; | ||
748 | } | ||
749 | current->total_link_count++; | 746 | current->total_link_count++; |
750 | if (current->total_link_count >= 40) | 747 | if (current->total_link_count >= 40) |
751 | return -ELOOP; | 748 | return -ELOOP; |
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h index 45174b534377..feb361e252ac 100644 --- a/fs/ubifs/debug.h +++ b/fs/ubifs/debug.h | |||
@@ -335,9 +335,9 @@ void dbg_debugfs_exit_fs(struct ubifs_info *c); | |||
335 | #define DBGKEY(key) ((char *)(key)) | 335 | #define DBGKEY(key) ((char *)(key)) |
336 | #define DBGKEY1(key) ((char *)(key)) | 336 | #define DBGKEY1(key) ((char *)(key)) |
337 | 337 | ||
338 | #define ubifs_dbg_msg(fmt, ...) do { \ | 338 | #define ubifs_dbg_msg(fmt, ...) do { \ |
339 | if (0) \ | 339 | if (0) \ |
340 | pr_debug(fmt "\n", ##__VA_ARGS__); \ | 340 | printk(KERN_DEBUG fmt "\n", ##__VA_ARGS__); \ |
341 | } while (0) | 341 | } while (0) |
342 | 342 | ||
343 | #define dbg_dump_stack() | 343 | #define dbg_dump_stack() |
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index b9c172b3fbbe..673704fab748 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c | |||
@@ -70,9 +70,8 @@ xfs_synchronize_times( | |||
70 | } | 70 | } |
71 | 71 | ||
72 | /* | 72 | /* |
73 | * If the linux inode is valid, mark it dirty. | 73 | * If the linux inode is valid, mark it dirty, else mark the dirty state |
74 | * Used when committing a dirty inode into a transaction so that | 74 | * in the XFS inode to make sure we pick it up when reclaiming the inode. |
75 | * the inode will get written back by the linux code | ||
76 | */ | 75 | */ |
77 | void | 76 | void |
78 | xfs_mark_inode_dirty_sync( | 77 | xfs_mark_inode_dirty_sync( |
@@ -82,6 +81,10 @@ xfs_mark_inode_dirty_sync( | |||
82 | 81 | ||
83 | if (!(inode->i_state & (I_WILL_FREE|I_FREEING))) | 82 | if (!(inode->i_state & (I_WILL_FREE|I_FREEING))) |
84 | mark_inode_dirty_sync(inode); | 83 | mark_inode_dirty_sync(inode); |
84 | else { | ||
85 | barrier(); | ||
86 | ip->i_update_core = 1; | ||
87 | } | ||
85 | } | 88 | } |
86 | 89 | ||
87 | void | 90 | void |
@@ -92,6 +95,11 @@ xfs_mark_inode_dirty( | |||
92 | 95 | ||
93 | if (!(inode->i_state & (I_WILL_FREE|I_FREEING))) | 96 | if (!(inode->i_state & (I_WILL_FREE|I_FREEING))) |
94 | mark_inode_dirty(inode); | 97 | mark_inode_dirty(inode); |
98 | else { | ||
99 | barrier(); | ||
100 | ip->i_update_core = 1; | ||
101 | } | ||
102 | |||
95 | } | 103 | } |
96 | 104 | ||
97 | /* | 105 | /* |
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 9a72dda58bd0..2366c54cc4fa 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c | |||
@@ -356,6 +356,8 @@ xfs_parseargs( | |||
356 | mp->m_flags |= XFS_MOUNT_DELAYLOG; | 356 | mp->m_flags |= XFS_MOUNT_DELAYLOG; |
357 | } else if (!strcmp(this_char, MNTOPT_NODELAYLOG)) { | 357 | } else if (!strcmp(this_char, MNTOPT_NODELAYLOG)) { |
358 | mp->m_flags &= ~XFS_MOUNT_DELAYLOG; | 358 | mp->m_flags &= ~XFS_MOUNT_DELAYLOG; |
359 | xfs_warn(mp, | ||
360 | "nodelaylog is deprecated and will be removed in Linux 3.3"); | ||
359 | } else if (!strcmp(this_char, MNTOPT_DISCARD)) { | 361 | } else if (!strcmp(this_char, MNTOPT_DISCARD)) { |
360 | mp->m_flags |= XFS_MOUNT_DISCARD; | 362 | mp->m_flags |= XFS_MOUNT_DISCARD; |
361 | } else if (!strcmp(this_char, MNTOPT_NODISCARD)) { | 363 | } else if (!strcmp(this_char, MNTOPT_NODISCARD)) { |
@@ -877,33 +879,17 @@ xfs_log_inode( | |||
877 | struct xfs_trans *tp; | 879 | struct xfs_trans *tp; |
878 | int error; | 880 | int error; |
879 | 881 | ||
880 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | ||
881 | tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS); | 882 | tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS); |
882 | error = xfs_trans_reserve(tp, 0, XFS_FSYNC_TS_LOG_RES(mp), 0, 0, 0); | 883 | error = xfs_trans_reserve(tp, 0, XFS_FSYNC_TS_LOG_RES(mp), 0, 0, 0); |
883 | |||
884 | if (error) { | 884 | if (error) { |
885 | xfs_trans_cancel(tp, 0); | 885 | xfs_trans_cancel(tp, 0); |
886 | /* we need to return with the lock hold shared */ | ||
887 | xfs_ilock(ip, XFS_ILOCK_SHARED); | ||
888 | return error; | 886 | return error; |
889 | } | 887 | } |
890 | 888 | ||
891 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 889 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
892 | 890 | xfs_trans_ijoin_ref(tp, ip, XFS_ILOCK_EXCL); | |
893 | /* | ||
894 | * Note - it's possible that we might have pushed ourselves out of the | ||
895 | * way during trans_reserve which would flush the inode. But there's | ||
896 | * no guarantee that the inode buffer has actually gone out yet (it's | ||
897 | * delwri). Plus the buffer could be pinned anyway if it's part of | ||
898 | * an inode in another recent transaction. So we play it safe and | ||
899 | * fire off the transaction anyway. | ||
900 | */ | ||
901 | xfs_trans_ijoin(tp, ip); | ||
902 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 891 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
903 | error = xfs_trans_commit(tp, 0); | 892 | return xfs_trans_commit(tp, 0); |
904 | xfs_ilock_demote(ip, XFS_ILOCK_EXCL); | ||
905 | |||
906 | return error; | ||
907 | } | 893 | } |
908 | 894 | ||
909 | STATIC int | 895 | STATIC int |
@@ -918,7 +904,9 @@ xfs_fs_write_inode( | |||
918 | trace_xfs_write_inode(ip); | 904 | trace_xfs_write_inode(ip); |
919 | 905 | ||
920 | if (XFS_FORCED_SHUTDOWN(mp)) | 906 | if (XFS_FORCED_SHUTDOWN(mp)) |
921 | return XFS_ERROR(EIO); | 907 | return -XFS_ERROR(EIO); |
908 | if (!ip->i_update_core) | ||
909 | return 0; | ||
922 | 910 | ||
923 | if (wbc->sync_mode == WB_SYNC_ALL) { | 911 | if (wbc->sync_mode == WB_SYNC_ALL) { |
924 | /* | 912 | /* |
@@ -929,12 +917,10 @@ xfs_fs_write_inode( | |||
929 | * of synchronous log foces dramatically. | 917 | * of synchronous log foces dramatically. |
930 | */ | 918 | */ |
931 | xfs_ioend_wait(ip); | 919 | xfs_ioend_wait(ip); |
932 | xfs_ilock(ip, XFS_ILOCK_SHARED); | 920 | error = xfs_log_inode(ip); |
933 | if (ip->i_update_core) { | 921 | if (error) |
934 | error = xfs_log_inode(ip); | 922 | goto out; |
935 | if (error) | 923 | return 0; |
936 | goto out_unlock; | ||
937 | } | ||
938 | } else { | 924 | } else { |
939 | /* | 925 | /* |
940 | * We make this non-blocking if the inode is contended, return | 926 | * We make this non-blocking if the inode is contended, return |