diff options
Diffstat (limited to 'fs')
158 files changed, 2156 insertions, 1855 deletions
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index e78956cbd702..34c59f14a1c9 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h | |||
@@ -144,7 +144,7 @@ extern void v9fs_session_close(struct v9fs_session_info *v9ses); | |||
144 | extern void v9fs_session_cancel(struct v9fs_session_info *v9ses); | 144 | extern void v9fs_session_cancel(struct v9fs_session_info *v9ses); |
145 | extern void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses); | 145 | extern void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses); |
146 | extern struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, | 146 | extern struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, |
147 | struct nameidata *nameidata); | 147 | unsigned int flags); |
148 | extern int v9fs_vfs_unlink(struct inode *i, struct dentry *d); | 148 | extern int v9fs_vfs_unlink(struct inode *i, struct dentry *d); |
149 | extern int v9fs_vfs_rmdir(struct inode *i, struct dentry *d); | 149 | extern int v9fs_vfs_rmdir(struct inode *i, struct dentry *d); |
150 | extern int v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, | 150 | extern int v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, |
diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c index d529437ff442..64600b5d0522 100644 --- a/fs/9p/vfs_dentry.c +++ b/fs/9p/vfs_dentry.c | |||
@@ -100,13 +100,13 @@ static void v9fs_dentry_release(struct dentry *dentry) | |||
100 | } | 100 | } |
101 | } | 101 | } |
102 | 102 | ||
103 | static int v9fs_lookup_revalidate(struct dentry *dentry, struct nameidata *nd) | 103 | static int v9fs_lookup_revalidate(struct dentry *dentry, unsigned int flags) |
104 | { | 104 | { |
105 | struct p9_fid *fid; | 105 | struct p9_fid *fid; |
106 | struct inode *inode; | 106 | struct inode *inode; |
107 | struct v9fs_inode *v9inode; | 107 | struct v9fs_inode *v9inode; |
108 | 108 | ||
109 | if (nd->flags & LOOKUP_RCU) | 109 | if (flags & LOOKUP_RCU) |
110 | return -ECHILD; | 110 | return -ECHILD; |
111 | 111 | ||
112 | inode = dentry->d_inode; | 112 | inode = dentry->d_inode; |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 57ccb7537dae..cbf9dbb1b2a2 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -712,88 +712,34 @@ error: | |||
712 | } | 712 | } |
713 | 713 | ||
714 | /** | 714 | /** |
715 | * v9fs_vfs_create - VFS hook to create files | 715 | * v9fs_vfs_create - VFS hook to create a regular file |
716 | * | ||
717 | * open(.., O_CREAT) is handled in v9fs_vfs_atomic_open(). This is only called | ||
718 | * for mknod(2). | ||
719 | * | ||
716 | * @dir: directory inode that is being created | 720 | * @dir: directory inode that is being created |
717 | * @dentry: dentry that is being deleted | 721 | * @dentry: dentry that is being deleted |
718 | * @mode: create permissions | 722 | * @mode: create permissions |
719 | * @nd: path information | ||
720 | * | 723 | * |
721 | */ | 724 | */ |
722 | 725 | ||
723 | static int | 726 | static int |
724 | v9fs_vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 727 | v9fs_vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
725 | struct nameidata *nd) | 728 | bool excl) |
726 | { | 729 | { |
727 | int err; | 730 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir); |
728 | u32 perm; | 731 | u32 perm = unixmode2p9mode(v9ses, mode); |
729 | int flags; | 732 | struct p9_fid *fid; |
730 | struct file *filp; | ||
731 | struct v9fs_inode *v9inode; | ||
732 | struct v9fs_session_info *v9ses; | ||
733 | struct p9_fid *fid, *inode_fid; | ||
734 | |||
735 | err = 0; | ||
736 | fid = NULL; | ||
737 | v9ses = v9fs_inode2v9ses(dir); | ||
738 | perm = unixmode2p9mode(v9ses, mode); | ||
739 | if (nd) | ||
740 | flags = nd->intent.open.flags; | ||
741 | else | ||
742 | flags = O_RDWR; | ||
743 | 733 | ||
744 | fid = v9fs_create(v9ses, dir, dentry, NULL, perm, | 734 | /* P9_OEXCL? */ |
745 | v9fs_uflags2omode(flags, | 735 | fid = v9fs_create(v9ses, dir, dentry, NULL, perm, P9_ORDWR); |
746 | v9fs_proto_dotu(v9ses))); | 736 | if (IS_ERR(fid)) |
747 | if (IS_ERR(fid)) { | 737 | return PTR_ERR(fid); |
748 | err = PTR_ERR(fid); | ||
749 | fid = NULL; | ||
750 | goto error; | ||
751 | } | ||
752 | 738 | ||
753 | v9fs_invalidate_inode_attr(dir); | 739 | v9fs_invalidate_inode_attr(dir); |
754 | /* if we are opening a file, assign the open fid to the file */ | 740 | p9_client_clunk(fid); |
755 | if (nd) { | ||
756 | v9inode = V9FS_I(dentry->d_inode); | ||
757 | mutex_lock(&v9inode->v_mutex); | ||
758 | if (v9ses->cache && !v9inode->writeback_fid && | ||
759 | ((flags & O_ACCMODE) != O_RDONLY)) { | ||
760 | /* | ||
761 | * clone a fid and add it to writeback_fid | ||
762 | * we do it during open time instead of | ||
763 | * page dirty time via write_begin/page_mkwrite | ||
764 | * because we want write after unlink usecase | ||
765 | * to work. | ||
766 | */ | ||
767 | inode_fid = v9fs_writeback_fid(dentry); | ||
768 | if (IS_ERR(inode_fid)) { | ||
769 | err = PTR_ERR(inode_fid); | ||
770 | mutex_unlock(&v9inode->v_mutex); | ||
771 | goto error; | ||
772 | } | ||
773 | v9inode->writeback_fid = (void *) inode_fid; | ||
774 | } | ||
775 | mutex_unlock(&v9inode->v_mutex); | ||
776 | filp = lookup_instantiate_filp(nd, dentry, generic_file_open); | ||
777 | if (IS_ERR(filp)) { | ||
778 | err = PTR_ERR(filp); | ||
779 | goto error; | ||
780 | } | ||
781 | |||
782 | filp->private_data = fid; | ||
783 | #ifdef CONFIG_9P_FSCACHE | ||
784 | if (v9ses->cache) | ||
785 | v9fs_cache_inode_set_cookie(dentry->d_inode, filp); | ||
786 | #endif | ||
787 | } else | ||
788 | p9_client_clunk(fid); | ||
789 | 741 | ||
790 | return 0; | 742 | return 0; |
791 | |||
792 | error: | ||
793 | if (fid) | ||
794 | p9_client_clunk(fid); | ||
795 | |||
796 | return err; | ||
797 | } | 743 | } |
798 | 744 | ||
799 | /** | 745 | /** |
@@ -839,7 +785,7 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode | |||
839 | */ | 785 | */ |
840 | 786 | ||
841 | struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, | 787 | struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, |
842 | struct nameidata *nameidata) | 788 | unsigned int flags) |
843 | { | 789 | { |
844 | struct dentry *res; | 790 | struct dentry *res; |
845 | struct super_block *sb; | 791 | struct super_block *sb; |
@@ -849,8 +795,8 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, | |||
849 | char *name; | 795 | char *name; |
850 | int result = 0; | 796 | int result = 0; |
851 | 797 | ||
852 | p9_debug(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n", | 798 | p9_debug(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p flags: %x\n", |
853 | dir, dentry->d_name.name, dentry, nameidata); | 799 | dir, dentry->d_name.name, dentry, flags); |
854 | 800 | ||
855 | if (dentry->d_name.len > NAME_MAX) | 801 | if (dentry->d_name.len > NAME_MAX) |
856 | return ERR_PTR(-ENAMETOOLONG); | 802 | return ERR_PTR(-ENAMETOOLONG); |
@@ -910,6 +856,86 @@ error: | |||
910 | return ERR_PTR(result); | 856 | return ERR_PTR(result); |
911 | } | 857 | } |
912 | 858 | ||
859 | static int | ||
860 | v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry, | ||
861 | struct file *file, unsigned flags, umode_t mode, | ||
862 | int *opened) | ||
863 | { | ||
864 | int err; | ||
865 | u32 perm; | ||
866 | struct v9fs_inode *v9inode; | ||
867 | struct v9fs_session_info *v9ses; | ||
868 | struct p9_fid *fid, *inode_fid; | ||
869 | struct dentry *res = NULL; | ||
870 | |||
871 | if (d_unhashed(dentry)) { | ||
872 | res = v9fs_vfs_lookup(dir, dentry, 0); | ||
873 | if (IS_ERR(res)) | ||
874 | return PTR_ERR(res); | ||
875 | |||
876 | if (res) | ||
877 | dentry = res; | ||
878 | } | ||
879 | |||
880 | /* Only creates */ | ||
881 | if (!(flags & O_CREAT) || dentry->d_inode) | ||
882 | return finish_no_open(file, res); | ||
883 | |||
884 | err = 0; | ||
885 | fid = NULL; | ||
886 | v9ses = v9fs_inode2v9ses(dir); | ||
887 | perm = unixmode2p9mode(v9ses, mode); | ||
888 | fid = v9fs_create(v9ses, dir, dentry, NULL, perm, | ||
889 | v9fs_uflags2omode(flags, | ||
890 | v9fs_proto_dotu(v9ses))); | ||
891 | if (IS_ERR(fid)) { | ||
892 | err = PTR_ERR(fid); | ||
893 | fid = NULL; | ||
894 | goto error; | ||
895 | } | ||
896 | |||
897 | v9fs_invalidate_inode_attr(dir); | ||
898 | v9inode = V9FS_I(dentry->d_inode); | ||
899 | mutex_lock(&v9inode->v_mutex); | ||
900 | if (v9ses->cache && !v9inode->writeback_fid && | ||
901 | ((flags & O_ACCMODE) != O_RDONLY)) { | ||
902 | /* | ||
903 | * clone a fid and add it to writeback_fid | ||
904 | * we do it during open time instead of | ||
905 | * page dirty time via write_begin/page_mkwrite | ||
906 | * because we want write after unlink usecase | ||
907 | * to work. | ||
908 | */ | ||
909 | inode_fid = v9fs_writeback_fid(dentry); | ||
910 | if (IS_ERR(inode_fid)) { | ||
911 | err = PTR_ERR(inode_fid); | ||
912 | mutex_unlock(&v9inode->v_mutex); | ||
913 | goto error; | ||
914 | } | ||
915 | v9inode->writeback_fid = (void *) inode_fid; | ||
916 | } | ||
917 | mutex_unlock(&v9inode->v_mutex); | ||
918 | err = finish_open(file, dentry, generic_file_open, opened); | ||
919 | if (err) | ||
920 | goto error; | ||
921 | |||
922 | file->private_data = fid; | ||
923 | #ifdef CONFIG_9P_FSCACHE | ||
924 | if (v9ses->cache) | ||
925 | v9fs_cache_inode_set_cookie(dentry->d_inode, file); | ||
926 | #endif | ||
927 | |||
928 | *opened |= FILE_CREATED; | ||
929 | out: | ||
930 | dput(res); | ||
931 | return err; | ||
932 | |||
933 | error: | ||
934 | if (fid) | ||
935 | p9_client_clunk(fid); | ||
936 | goto out; | ||
937 | } | ||
938 | |||
913 | /** | 939 | /** |
914 | * v9fs_vfs_unlink - VFS unlink hook to delete an inode | 940 | * v9fs_vfs_unlink - VFS unlink hook to delete an inode |
915 | * @i: inode that is being unlinked | 941 | * @i: inode that is being unlinked |
@@ -1488,6 +1514,7 @@ out: | |||
1488 | static const struct inode_operations v9fs_dir_inode_operations_dotu = { | 1514 | static const struct inode_operations v9fs_dir_inode_operations_dotu = { |
1489 | .create = v9fs_vfs_create, | 1515 | .create = v9fs_vfs_create, |
1490 | .lookup = v9fs_vfs_lookup, | 1516 | .lookup = v9fs_vfs_lookup, |
1517 | .atomic_open = v9fs_vfs_atomic_open, | ||
1491 | .symlink = v9fs_vfs_symlink, | 1518 | .symlink = v9fs_vfs_symlink, |
1492 | .link = v9fs_vfs_link, | 1519 | .link = v9fs_vfs_link, |
1493 | .unlink = v9fs_vfs_unlink, | 1520 | .unlink = v9fs_vfs_unlink, |
@@ -1502,6 +1529,7 @@ static const struct inode_operations v9fs_dir_inode_operations_dotu = { | |||
1502 | static const struct inode_operations v9fs_dir_inode_operations = { | 1529 | static const struct inode_operations v9fs_dir_inode_operations = { |
1503 | .create = v9fs_vfs_create, | 1530 | .create = v9fs_vfs_create, |
1504 | .lookup = v9fs_vfs_lookup, | 1531 | .lookup = v9fs_vfs_lookup, |
1532 | .atomic_open = v9fs_vfs_atomic_open, | ||
1505 | .unlink = v9fs_vfs_unlink, | 1533 | .unlink = v9fs_vfs_unlink, |
1506 | .mkdir = v9fs_vfs_mkdir, | 1534 | .mkdir = v9fs_vfs_mkdir, |
1507 | .rmdir = v9fs_vfs_rmdir, | 1535 | .rmdir = v9fs_vfs_rmdir, |
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index e3dd2a1e2bfc..40895546e103 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c | |||
@@ -230,20 +230,25 @@ int v9fs_open_to_dotl_flags(int flags) | |||
230 | * @dir: directory inode that is being created | 230 | * @dir: directory inode that is being created |
231 | * @dentry: dentry that is being deleted | 231 | * @dentry: dentry that is being deleted |
232 | * @mode: create permissions | 232 | * @mode: create permissions |
233 | * @nd: path information | ||
234 | * | 233 | * |
235 | */ | 234 | */ |
236 | 235 | ||
237 | static int | 236 | static int |
238 | v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode, | 237 | v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode, |
239 | struct nameidata *nd) | 238 | bool excl) |
239 | { | ||
240 | return v9fs_vfs_mknod_dotl(dir, dentry, omode, 0); | ||
241 | } | ||
242 | |||
243 | static int | ||
244 | v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, | ||
245 | struct file *file, unsigned flags, umode_t omode, | ||
246 | int *opened) | ||
240 | { | 247 | { |
241 | int err = 0; | 248 | int err = 0; |
242 | gid_t gid; | 249 | gid_t gid; |
243 | int flags; | ||
244 | umode_t mode; | 250 | umode_t mode; |
245 | char *name = NULL; | 251 | char *name = NULL; |
246 | struct file *filp; | ||
247 | struct p9_qid qid; | 252 | struct p9_qid qid; |
248 | struct inode *inode; | 253 | struct inode *inode; |
249 | struct p9_fid *fid = NULL; | 254 | struct p9_fid *fid = NULL; |
@@ -251,19 +256,23 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode, | |||
251 | struct p9_fid *dfid, *ofid, *inode_fid; | 256 | struct p9_fid *dfid, *ofid, *inode_fid; |
252 | struct v9fs_session_info *v9ses; | 257 | struct v9fs_session_info *v9ses; |
253 | struct posix_acl *pacl = NULL, *dacl = NULL; | 258 | struct posix_acl *pacl = NULL, *dacl = NULL; |
259 | struct dentry *res = NULL; | ||
254 | 260 | ||
255 | v9ses = v9fs_inode2v9ses(dir); | 261 | if (d_unhashed(dentry)) { |
256 | if (nd) | 262 | res = v9fs_vfs_lookup(dir, dentry, 0); |
257 | flags = nd->intent.open.flags; | 263 | if (IS_ERR(res)) |
258 | else { | 264 | return PTR_ERR(res); |
259 | /* | 265 | |
260 | * create call without LOOKUP_OPEN is due | 266 | if (res) |
261 | * to mknod of regular files. So use mknod | 267 | dentry = res; |
262 | * operation. | ||
263 | */ | ||
264 | return v9fs_vfs_mknod_dotl(dir, dentry, omode, 0); | ||
265 | } | 268 | } |
266 | 269 | ||
270 | /* Only creates */ | ||
271 | if (!(flags & O_CREAT) || dentry->d_inode) | ||
272 | return finish_no_open(file, res); | ||
273 | |||
274 | v9ses = v9fs_inode2v9ses(dir); | ||
275 | |||
267 | name = (char *) dentry->d_name.name; | 276 | name = (char *) dentry->d_name.name; |
268 | p9_debug(P9_DEBUG_VFS, "name:%s flags:0x%x mode:0x%hx\n", | 277 | p9_debug(P9_DEBUG_VFS, "name:%s flags:0x%x mode:0x%hx\n", |
269 | name, flags, omode); | 278 | name, flags, omode); |
@@ -272,7 +281,7 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode, | |||
272 | if (IS_ERR(dfid)) { | 281 | if (IS_ERR(dfid)) { |
273 | err = PTR_ERR(dfid); | 282 | err = PTR_ERR(dfid); |
274 | p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err); | 283 | p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err); |
275 | return err; | 284 | goto out; |
276 | } | 285 | } |
277 | 286 | ||
278 | /* clone a fid to use for creation */ | 287 | /* clone a fid to use for creation */ |
@@ -280,7 +289,7 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode, | |||
280 | if (IS_ERR(ofid)) { | 289 | if (IS_ERR(ofid)) { |
281 | err = PTR_ERR(ofid); | 290 | err = PTR_ERR(ofid); |
282 | p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); | 291 | p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); |
283 | return err; | 292 | goto out; |
284 | } | 293 | } |
285 | 294 | ||
286 | gid = v9fs_get_fsgid_for_create(dir); | 295 | gid = v9fs_get_fsgid_for_create(dir); |
@@ -345,17 +354,18 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode, | |||
345 | } | 354 | } |
346 | mutex_unlock(&v9inode->v_mutex); | 355 | mutex_unlock(&v9inode->v_mutex); |
347 | /* Since we are opening a file, assign the open fid to the file */ | 356 | /* Since we are opening a file, assign the open fid to the file */ |
348 | filp = lookup_instantiate_filp(nd, dentry, generic_file_open); | 357 | err = finish_open(file, dentry, generic_file_open, opened); |
349 | if (IS_ERR(filp)) { | 358 | if (err) |
350 | err = PTR_ERR(filp); | ||
351 | goto err_clunk_old_fid; | 359 | goto err_clunk_old_fid; |
352 | } | 360 | file->private_data = ofid; |
353 | filp->private_data = ofid; | ||
354 | #ifdef CONFIG_9P_FSCACHE | 361 | #ifdef CONFIG_9P_FSCACHE |
355 | if (v9ses->cache) | 362 | if (v9ses->cache) |
356 | v9fs_cache_inode_set_cookie(inode, filp); | 363 | v9fs_cache_inode_set_cookie(inode, file); |
357 | #endif | 364 | #endif |
358 | return 0; | 365 | *opened |= FILE_CREATED; |
366 | out: | ||
367 | dput(res); | ||
368 | return err; | ||
359 | 369 | ||
360 | error: | 370 | error: |
361 | if (fid) | 371 | if (fid) |
@@ -364,7 +374,7 @@ err_clunk_old_fid: | |||
364 | if (ofid) | 374 | if (ofid) |
365 | p9_client_clunk(ofid); | 375 | p9_client_clunk(ofid); |
366 | v9fs_set_create_acl(NULL, &dacl, &pacl); | 376 | v9fs_set_create_acl(NULL, &dacl, &pacl); |
367 | return err; | 377 | goto out; |
368 | } | 378 | } |
369 | 379 | ||
370 | /** | 380 | /** |
@@ -982,6 +992,7 @@ out: | |||
982 | 992 | ||
983 | const struct inode_operations v9fs_dir_inode_operations_dotl = { | 993 | const struct inode_operations v9fs_dir_inode_operations_dotl = { |
984 | .create = v9fs_vfs_create_dotl, | 994 | .create = v9fs_vfs_create_dotl, |
995 | .atomic_open = v9fs_vfs_atomic_open_dotl, | ||
985 | .lookup = v9fs_vfs_lookup, | 996 | .lookup = v9fs_vfs_lookup, |
986 | .link = v9fs_vfs_link_dotl, | 997 | .link = v9fs_vfs_link_dotl, |
987 | .symlink = v9fs_vfs_symlink_dotl, | 998 | .symlink = v9fs_vfs_symlink_dotl, |
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index 8c92a9ba8330..137d50396898 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c | |||
@@ -89,7 +89,7 @@ v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses, | |||
89 | if (v9ses->cache) | 89 | if (v9ses->cache) |
90 | sb->s_bdi->ra_pages = (VM_MAX_READAHEAD * 1024)/PAGE_CACHE_SIZE; | 90 | sb->s_bdi->ra_pages = (VM_MAX_READAHEAD * 1024)/PAGE_CACHE_SIZE; |
91 | 91 | ||
92 | sb->s_flags = flags | MS_ACTIVE | MS_DIRSYNC | MS_NOATIME; | 92 | sb->s_flags |= MS_ACTIVE | MS_DIRSYNC | MS_NOATIME; |
93 | if (!v9ses->cache) | 93 | if (!v9ses->cache) |
94 | sb->s_flags |= MS_SYNCHRONOUS; | 94 | sb->s_flags |= MS_SYNCHRONOUS; |
95 | 95 | ||
@@ -137,7 +137,7 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags, | |||
137 | goto close_session; | 137 | goto close_session; |
138 | } | 138 | } |
139 | 139 | ||
140 | sb = sget(fs_type, NULL, v9fs_set_super, v9ses); | 140 | sb = sget(fs_type, NULL, v9fs_set_super, flags, v9ses); |
141 | if (IS_ERR(sb)) { | 141 | if (IS_ERR(sb)) { |
142 | retval = PTR_ERR(sb); | 142 | retval = PTR_ERR(sb); |
143 | goto clunk_fid; | 143 | goto clunk_fid; |
diff --git a/fs/adfs/dir.c b/fs/adfs/dir.c index 3d83075aaa2e..b3be2e7c5643 100644 --- a/fs/adfs/dir.c +++ b/fs/adfs/dir.c | |||
@@ -266,7 +266,7 @@ const struct dentry_operations adfs_dentry_operations = { | |||
266 | }; | 266 | }; |
267 | 267 | ||
268 | static struct dentry * | 268 | static struct dentry * |
269 | adfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | 269 | adfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) |
270 | { | 270 | { |
271 | struct inode *inode = NULL; | 271 | struct inode *inode = NULL; |
272 | struct object_info obj; | 272 | struct object_info obj; |
diff --git a/fs/adfs/super.c b/fs/adfs/super.c index 06fdcc9382c4..bdaec92353c2 100644 --- a/fs/adfs/super.c +++ b/fs/adfs/super.c | |||
@@ -246,7 +246,6 @@ static struct inode *adfs_alloc_inode(struct super_block *sb) | |||
246 | static void adfs_i_callback(struct rcu_head *head) | 246 | static void adfs_i_callback(struct rcu_head *head) |
247 | { | 247 | { |
248 | struct inode *inode = container_of(head, struct inode, i_rcu); | 248 | struct inode *inode = container_of(head, struct inode, i_rcu); |
249 | INIT_LIST_HEAD(&inode->i_dentry); | ||
250 | kmem_cache_free(adfs_inode_cachep, ADFS_I(inode)); | 249 | kmem_cache_free(adfs_inode_cachep, ADFS_I(inode)); |
251 | } | 250 | } |
252 | 251 | ||
diff --git a/fs/affs/affs.h b/fs/affs/affs.h index 1fceb320d2f2..6e216419f340 100644 --- a/fs/affs/affs.h +++ b/fs/affs/affs.h | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <linux/buffer_head.h> | 3 | #include <linux/buffer_head.h> |
4 | #include <linux/amigaffs.h> | 4 | #include <linux/amigaffs.h> |
5 | #include <linux/mutex.h> | 5 | #include <linux/mutex.h> |
6 | #include <linux/workqueue.h> | ||
6 | 7 | ||
7 | /* AmigaOS allows file names with up to 30 characters length. | 8 | /* AmigaOS allows file names with up to 30 characters length. |
8 | * Names longer than that will be silently truncated. If you | 9 | * Names longer than that will be silently truncated. If you |
@@ -100,6 +101,10 @@ struct affs_sb_info { | |||
100 | char *s_prefix; /* Prefix for volumes and assigns. */ | 101 | char *s_prefix; /* Prefix for volumes and assigns. */ |
101 | char s_volume[32]; /* Volume prefix for absolute symlinks. */ | 102 | char s_volume[32]; /* Volume prefix for absolute symlinks. */ |
102 | spinlock_t symlink_lock; /* protects the previous two */ | 103 | spinlock_t symlink_lock; /* protects the previous two */ |
104 | struct super_block *sb; /* the VFS superblock object */ | ||
105 | int work_queued; /* non-zero delayed work is queued */ | ||
106 | struct delayed_work sb_work; /* superblock flush delayed work */ | ||
107 | spinlock_t work_lock; /* protects sb_work and work_queued */ | ||
103 | }; | 108 | }; |
104 | 109 | ||
105 | #define SF_INTL 0x0001 /* International filesystem. */ | 110 | #define SF_INTL 0x0001 /* International filesystem. */ |
@@ -120,6 +125,8 @@ static inline struct affs_sb_info *AFFS_SB(struct super_block *sb) | |||
120 | return sb->s_fs_info; | 125 | return sb->s_fs_info; |
121 | } | 126 | } |
122 | 127 | ||
128 | void affs_mark_sb_dirty(struct super_block *sb); | ||
129 | |||
123 | /* amigaffs.c */ | 130 | /* amigaffs.c */ |
124 | 131 | ||
125 | extern int affs_insert_hash(struct inode *inode, struct buffer_head *bh); | 132 | extern int affs_insert_hash(struct inode *inode, struct buffer_head *bh); |
@@ -146,9 +153,9 @@ extern void affs_free_bitmap(struct super_block *sb); | |||
146 | /* namei.c */ | 153 | /* namei.c */ |
147 | 154 | ||
148 | extern int affs_hash_name(struct super_block *sb, const u8 *name, unsigned int len); | 155 | extern int affs_hash_name(struct super_block *sb, const u8 *name, unsigned int len); |
149 | extern struct dentry *affs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *); | 156 | extern struct dentry *affs_lookup(struct inode *dir, struct dentry *dentry, unsigned int); |
150 | extern int affs_unlink(struct inode *dir, struct dentry *dentry); | 157 | extern int affs_unlink(struct inode *dir, struct dentry *dentry); |
151 | extern int affs_create(struct inode *dir, struct dentry *dentry, umode_t mode, struct nameidata *); | 158 | extern int affs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool); |
152 | extern int affs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode); | 159 | extern int affs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode); |
153 | extern int affs_rmdir(struct inode *dir, struct dentry *dentry); | 160 | extern int affs_rmdir(struct inode *dir, struct dentry *dentry); |
154 | extern int affs_link(struct dentry *olddentry, struct inode *dir, | 161 | extern int affs_link(struct dentry *olddentry, struct inode *dir, |
diff --git a/fs/affs/amigaffs.c b/fs/affs/amigaffs.c index 52a6407682e6..eb82ee53ee0b 100644 --- a/fs/affs/amigaffs.c +++ b/fs/affs/amigaffs.c | |||
@@ -122,22 +122,16 @@ affs_remove_hash(struct inode *dir, struct buffer_head *rem_bh) | |||
122 | } | 122 | } |
123 | 123 | ||
124 | static void | 124 | static void |
125 | affs_fix_dcache(struct dentry *dentry, u32 entry_ino) | 125 | affs_fix_dcache(struct inode *inode, u32 entry_ino) |
126 | { | 126 | { |
127 | struct inode *inode = dentry->d_inode; | 127 | struct dentry *dentry; |
128 | void *data = dentry->d_fsdata; | 128 | struct hlist_node *p; |
129 | struct list_head *head, *next; | ||
130 | |||
131 | spin_lock(&inode->i_lock); | 129 | spin_lock(&inode->i_lock); |
132 | head = &inode->i_dentry; | 130 | hlist_for_each_entry(dentry, p, &inode->i_dentry, d_alias) { |
133 | next = head->next; | ||
134 | while (next != head) { | ||
135 | dentry = list_entry(next, struct dentry, d_alias); | ||
136 | if (entry_ino == (u32)(long)dentry->d_fsdata) { | 131 | if (entry_ino == (u32)(long)dentry->d_fsdata) { |
137 | dentry->d_fsdata = data; | 132 | dentry->d_fsdata = (void *)inode->i_ino; |
138 | break; | 133 | break; |
139 | } | 134 | } |
140 | next = next->next; | ||
141 | } | 135 | } |
142 | spin_unlock(&inode->i_lock); | 136 | spin_unlock(&inode->i_lock); |
143 | } | 137 | } |
@@ -177,7 +171,11 @@ affs_remove_link(struct dentry *dentry) | |||
177 | } | 171 | } |
178 | 172 | ||
179 | affs_lock_dir(dir); | 173 | affs_lock_dir(dir); |
180 | affs_fix_dcache(dentry, link_ino); | 174 | /* |
175 | * if there's a dentry for that block, make it | ||
176 | * refer to inode itself. | ||
177 | */ | ||
178 | affs_fix_dcache(inode, link_ino); | ||
181 | retval = affs_remove_hash(dir, link_bh); | 179 | retval = affs_remove_hash(dir, link_bh); |
182 | if (retval) { | 180 | if (retval) { |
183 | affs_unlock_dir(dir); | 181 | affs_unlock_dir(dir); |
diff --git a/fs/affs/bitmap.c b/fs/affs/bitmap.c index 3e262711ae06..6e0be43ef6ef 100644 --- a/fs/affs/bitmap.c +++ b/fs/affs/bitmap.c | |||
@@ -103,7 +103,7 @@ affs_free_block(struct super_block *sb, u32 block) | |||
103 | *(__be32 *)bh->b_data = cpu_to_be32(tmp - mask); | 103 | *(__be32 *)bh->b_data = cpu_to_be32(tmp - mask); |
104 | 104 | ||
105 | mark_buffer_dirty(bh); | 105 | mark_buffer_dirty(bh); |
106 | sb->s_dirt = 1; | 106 | affs_mark_sb_dirty(sb); |
107 | bm->bm_free++; | 107 | bm->bm_free++; |
108 | 108 | ||
109 | mutex_unlock(&sbi->s_bmlock); | 109 | mutex_unlock(&sbi->s_bmlock); |
@@ -248,7 +248,7 @@ find_bit: | |||
248 | *(__be32 *)bh->b_data = cpu_to_be32(tmp + mask); | 248 | *(__be32 *)bh->b_data = cpu_to_be32(tmp + mask); |
249 | 249 | ||
250 | mark_buffer_dirty(bh); | 250 | mark_buffer_dirty(bh); |
251 | sb->s_dirt = 1; | 251 | affs_mark_sb_dirty(sb); |
252 | 252 | ||
253 | mutex_unlock(&sbi->s_bmlock); | 253 | mutex_unlock(&sbi->s_bmlock); |
254 | 254 | ||
diff --git a/fs/affs/namei.c b/fs/affs/namei.c index 47806940aac0..ff65884a7839 100644 --- a/fs/affs/namei.c +++ b/fs/affs/namei.c | |||
@@ -211,7 +211,7 @@ affs_find_entry(struct inode *dir, struct dentry *dentry) | |||
211 | } | 211 | } |
212 | 212 | ||
213 | struct dentry * | 213 | struct dentry * |
214 | affs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | 214 | affs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) |
215 | { | 215 | { |
216 | struct super_block *sb = dir->i_sb; | 216 | struct super_block *sb = dir->i_sb; |
217 | struct buffer_head *bh; | 217 | struct buffer_head *bh; |
@@ -255,7 +255,7 @@ affs_unlink(struct inode *dir, struct dentry *dentry) | |||
255 | } | 255 | } |
256 | 256 | ||
257 | int | 257 | int |
258 | affs_create(struct inode *dir, struct dentry *dentry, umode_t mode, struct nameidata *nd) | 258 | affs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool excl) |
259 | { | 259 | { |
260 | struct super_block *sb = dir->i_sb; | 260 | struct super_block *sb = dir->i_sb; |
261 | struct inode *inode; | 261 | struct inode *inode; |
diff --git a/fs/affs/super.c b/fs/affs/super.c index 0782653a05a2..c70f1e5fc024 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/magic.h> | 17 | #include <linux/magic.h> |
18 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/writeback.h> | ||
20 | #include "affs.h" | 21 | #include "affs.h" |
21 | 22 | ||
22 | extern struct timezone sys_tz; | 23 | extern struct timezone sys_tz; |
@@ -25,15 +26,17 @@ static int affs_statfs(struct dentry *dentry, struct kstatfs *buf); | |||
25 | static int affs_remount (struct super_block *sb, int *flags, char *data); | 26 | static int affs_remount (struct super_block *sb, int *flags, char *data); |
26 | 27 | ||
27 | static void | 28 | static void |
28 | affs_commit_super(struct super_block *sb, int wait, int clean) | 29 | affs_commit_super(struct super_block *sb, int wait) |
29 | { | 30 | { |
30 | struct affs_sb_info *sbi = AFFS_SB(sb); | 31 | struct affs_sb_info *sbi = AFFS_SB(sb); |
31 | struct buffer_head *bh = sbi->s_root_bh; | 32 | struct buffer_head *bh = sbi->s_root_bh; |
32 | struct affs_root_tail *tail = AFFS_ROOT_TAIL(sb, bh); | 33 | struct affs_root_tail *tail = AFFS_ROOT_TAIL(sb, bh); |
33 | 34 | ||
34 | tail->bm_flag = cpu_to_be32(clean); | 35 | lock_buffer(bh); |
35 | secs_to_datestamp(get_seconds(), &tail->disk_change); | 36 | secs_to_datestamp(get_seconds(), &tail->disk_change); |
36 | affs_fix_checksum(sb, bh); | 37 | affs_fix_checksum(sb, bh); |
38 | unlock_buffer(bh); | ||
39 | |||
37 | mark_buffer_dirty(bh); | 40 | mark_buffer_dirty(bh); |
38 | if (wait) | 41 | if (wait) |
39 | sync_dirty_buffer(bh); | 42 | sync_dirty_buffer(bh); |
@@ -45,9 +48,7 @@ affs_put_super(struct super_block *sb) | |||
45 | struct affs_sb_info *sbi = AFFS_SB(sb); | 48 | struct affs_sb_info *sbi = AFFS_SB(sb); |
46 | pr_debug("AFFS: put_super()\n"); | 49 | pr_debug("AFFS: put_super()\n"); |
47 | 50 | ||
48 | if (!(sb->s_flags & MS_RDONLY) && sb->s_dirt) | 51 | cancel_delayed_work_sync(&sbi->sb_work); |
49 | affs_commit_super(sb, 1, 1); | ||
50 | |||
51 | kfree(sbi->s_prefix); | 52 | kfree(sbi->s_prefix); |
52 | affs_free_bitmap(sb); | 53 | affs_free_bitmap(sb); |
53 | affs_brelse(sbi->s_root_bh); | 54 | affs_brelse(sbi->s_root_bh); |
@@ -55,26 +56,43 @@ affs_put_super(struct super_block *sb) | |||
55 | sb->s_fs_info = NULL; | 56 | sb->s_fs_info = NULL; |
56 | } | 57 | } |
57 | 58 | ||
58 | static void | 59 | static int |
59 | affs_write_super(struct super_block *sb) | 60 | affs_sync_fs(struct super_block *sb, int wait) |
60 | { | 61 | { |
61 | lock_super(sb); | 62 | affs_commit_super(sb, wait); |
62 | if (!(sb->s_flags & MS_RDONLY)) | 63 | return 0; |
63 | affs_commit_super(sb, 1, 2); | 64 | } |
64 | sb->s_dirt = 0; | 65 | |
65 | unlock_super(sb); | 66 | static void flush_superblock(struct work_struct *work) |
67 | { | ||
68 | struct affs_sb_info *sbi; | ||
69 | struct super_block *sb; | ||
70 | |||
71 | sbi = container_of(work, struct affs_sb_info, sb_work.work); | ||
72 | sb = sbi->sb; | ||
66 | 73 | ||
67 | pr_debug("AFFS: write_super() at %lu, clean=2\n", get_seconds()); | 74 | spin_lock(&sbi->work_lock); |
75 | sbi->work_queued = 0; | ||
76 | spin_unlock(&sbi->work_lock); | ||
77 | |||
78 | affs_commit_super(sb, 1); | ||
68 | } | 79 | } |
69 | 80 | ||
70 | static int | 81 | void affs_mark_sb_dirty(struct super_block *sb) |
71 | affs_sync_fs(struct super_block *sb, int wait) | ||
72 | { | 82 | { |
73 | lock_super(sb); | 83 | struct affs_sb_info *sbi = AFFS_SB(sb); |
74 | affs_commit_super(sb, wait, 2); | 84 | unsigned long delay; |
75 | sb->s_dirt = 0; | 85 | |
76 | unlock_super(sb); | 86 | if (sb->s_flags & MS_RDONLY) |
77 | return 0; | 87 | return; |
88 | |||
89 | spin_lock(&sbi->work_lock); | ||
90 | if (!sbi->work_queued) { | ||
91 | delay = msecs_to_jiffies(dirty_writeback_interval * 10); | ||
92 | queue_delayed_work(system_long_wq, &sbi->sb_work, delay); | ||
93 | sbi->work_queued = 1; | ||
94 | } | ||
95 | spin_unlock(&sbi->work_lock); | ||
78 | } | 96 | } |
79 | 97 | ||
80 | static struct kmem_cache * affs_inode_cachep; | 98 | static struct kmem_cache * affs_inode_cachep; |
@@ -138,7 +156,6 @@ static const struct super_operations affs_sops = { | |||
138 | .write_inode = affs_write_inode, | 156 | .write_inode = affs_write_inode, |
139 | .evict_inode = affs_evict_inode, | 157 | .evict_inode = affs_evict_inode, |
140 | .put_super = affs_put_super, | 158 | .put_super = affs_put_super, |
141 | .write_super = affs_write_super, | ||
142 | .sync_fs = affs_sync_fs, | 159 | .sync_fs = affs_sync_fs, |
143 | .statfs = affs_statfs, | 160 | .statfs = affs_statfs, |
144 | .remount_fs = affs_remount, | 161 | .remount_fs = affs_remount, |
@@ -305,8 +322,11 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent) | |||
305 | return -ENOMEM; | 322 | return -ENOMEM; |
306 | 323 | ||
307 | sb->s_fs_info = sbi; | 324 | sb->s_fs_info = sbi; |
325 | sbi->sb = sb; | ||
308 | mutex_init(&sbi->s_bmlock); | 326 | mutex_init(&sbi->s_bmlock); |
309 | spin_lock_init(&sbi->symlink_lock); | 327 | spin_lock_init(&sbi->symlink_lock); |
328 | spin_lock_init(&sbi->work_lock); | ||
329 | INIT_DELAYED_WORK(&sbi->sb_work, flush_superblock); | ||
310 | 330 | ||
311 | if (!parse_options(data,&uid,&gid,&i,&reserved,&root_block, | 331 | if (!parse_options(data,&uid,&gid,&i,&reserved,&root_block, |
312 | &blocksize,&sbi->s_prefix, | 332 | &blocksize,&sbi->s_prefix, |
@@ -531,6 +551,7 @@ affs_remount(struct super_block *sb, int *flags, char *data) | |||
531 | return -EINVAL; | 551 | return -EINVAL; |
532 | } | 552 | } |
533 | 553 | ||
554 | flush_delayed_work_sync(&sbi->sb_work); | ||
534 | replace_mount_options(sb, new_opts); | 555 | replace_mount_options(sb, new_opts); |
535 | 556 | ||
536 | sbi->s_flags = mount_flags; | 557 | sbi->s_flags = mount_flags; |
@@ -549,10 +570,9 @@ affs_remount(struct super_block *sb, int *flags, char *data) | |||
549 | if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) | 570 | if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) |
550 | return 0; | 571 | return 0; |
551 | 572 | ||
552 | if (*flags & MS_RDONLY) { | 573 | if (*flags & MS_RDONLY) |
553 | affs_write_super(sb); | ||
554 | affs_free_bitmap(sb); | 574 | affs_free_bitmap(sb); |
555 | } else | 575 | else |
556 | res = affs_init_bitmap(sb, flags); | 576 | res = affs_init_bitmap(sb, flags); |
557 | 577 | ||
558 | return res; | 578 | return res; |
diff --git a/fs/afs/dir.c b/fs/afs/dir.c index e22dc4b4a503..db477906ba4f 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c | |||
@@ -20,16 +20,16 @@ | |||
20 | #include "internal.h" | 20 | #include "internal.h" |
21 | 21 | ||
22 | static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, | 22 | static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, |
23 | struct nameidata *nd); | 23 | unsigned int flags); |
24 | static int afs_dir_open(struct inode *inode, struct file *file); | 24 | static int afs_dir_open(struct inode *inode, struct file *file); |
25 | static int afs_readdir(struct file *file, void *dirent, filldir_t filldir); | 25 | static int afs_readdir(struct file *file, void *dirent, filldir_t filldir); |
26 | static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd); | 26 | static int afs_d_revalidate(struct dentry *dentry, unsigned int flags); |
27 | static int afs_d_delete(const struct dentry *dentry); | 27 | static int afs_d_delete(const struct dentry *dentry); |
28 | static void afs_d_release(struct dentry *dentry); | 28 | static void afs_d_release(struct dentry *dentry); |
29 | static int afs_lookup_filldir(void *_cookie, const char *name, int nlen, | 29 | static int afs_lookup_filldir(void *_cookie, const char *name, int nlen, |
30 | loff_t fpos, u64 ino, unsigned dtype); | 30 | loff_t fpos, u64 ino, unsigned dtype); |
31 | static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 31 | static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
32 | struct nameidata *nd); | 32 | bool excl); |
33 | static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode); | 33 | static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode); |
34 | static int afs_rmdir(struct inode *dir, struct dentry *dentry); | 34 | static int afs_rmdir(struct inode *dir, struct dentry *dentry); |
35 | static int afs_unlink(struct inode *dir, struct dentry *dentry); | 35 | static int afs_unlink(struct inode *dir, struct dentry *dentry); |
@@ -516,7 +516,7 @@ out: | |||
516 | * look up an entry in a directory | 516 | * look up an entry in a directory |
517 | */ | 517 | */ |
518 | static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, | 518 | static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, |
519 | struct nameidata *nd) | 519 | unsigned int flags) |
520 | { | 520 | { |
521 | struct afs_vnode *vnode; | 521 | struct afs_vnode *vnode; |
522 | struct afs_fid fid; | 522 | struct afs_fid fid; |
@@ -598,7 +598,7 @@ success: | |||
598 | * - NOTE! the hit can be a negative hit too, so we can't assume we have an | 598 | * - NOTE! the hit can be a negative hit too, so we can't assume we have an |
599 | * inode | 599 | * inode |
600 | */ | 600 | */ |
601 | static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd) | 601 | static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) |
602 | { | 602 | { |
603 | struct afs_vnode *vnode, *dir; | 603 | struct afs_vnode *vnode, *dir; |
604 | struct afs_fid uninitialized_var(fid); | 604 | struct afs_fid uninitialized_var(fid); |
@@ -607,7 +607,7 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
607 | void *dir_version; | 607 | void *dir_version; |
608 | int ret; | 608 | int ret; |
609 | 609 | ||
610 | if (nd->flags & LOOKUP_RCU) | 610 | if (flags & LOOKUP_RCU) |
611 | return -ECHILD; | 611 | return -ECHILD; |
612 | 612 | ||
613 | vnode = AFS_FS_I(dentry->d_inode); | 613 | vnode = AFS_FS_I(dentry->d_inode); |
@@ -949,7 +949,7 @@ error: | |||
949 | * create a regular file on an AFS filesystem | 949 | * create a regular file on an AFS filesystem |
950 | */ | 950 | */ |
951 | static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 951 | static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
952 | struct nameidata *nd) | 952 | bool excl) |
953 | { | 953 | { |
954 | struct afs_file_status status; | 954 | struct afs_file_status status; |
955 | struct afs_callback cb; | 955 | struct afs_callback cb; |
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c index 298cf8919ec7..9682c33d5daf 100644 --- a/fs/afs/mntpt.c +++ b/fs/afs/mntpt.c | |||
@@ -22,7 +22,7 @@ | |||
22 | 22 | ||
23 | static struct dentry *afs_mntpt_lookup(struct inode *dir, | 23 | static struct dentry *afs_mntpt_lookup(struct inode *dir, |
24 | struct dentry *dentry, | 24 | struct dentry *dentry, |
25 | struct nameidata *nd); | 25 | unsigned int flags); |
26 | static int afs_mntpt_open(struct inode *inode, struct file *file); | 26 | static int afs_mntpt_open(struct inode *inode, struct file *file); |
27 | static void afs_mntpt_expiry_timed_out(struct work_struct *work); | 27 | static void afs_mntpt_expiry_timed_out(struct work_struct *work); |
28 | 28 | ||
@@ -104,7 +104,7 @@ out: | |||
104 | */ | 104 | */ |
105 | static struct dentry *afs_mntpt_lookup(struct inode *dir, | 105 | static struct dentry *afs_mntpt_lookup(struct inode *dir, |
106 | struct dentry *dentry, | 106 | struct dentry *dentry, |
107 | struct nameidata *nd) | 107 | unsigned int flags) |
108 | { | 108 | { |
109 | _enter("%p,%p{%p{%s},%s}", | 109 | _enter("%p,%p{%p{%s},%s}", |
110 | dir, | 110 | dir, |
diff --git a/fs/afs/super.c b/fs/afs/super.c index f02b31e7e648..df8c6047c2a1 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c | |||
@@ -395,7 +395,7 @@ static struct dentry *afs_mount(struct file_system_type *fs_type, | |||
395 | as->volume = vol; | 395 | as->volume = vol; |
396 | 396 | ||
397 | /* allocate a deviceless superblock */ | 397 | /* allocate a deviceless superblock */ |
398 | sb = sget(fs_type, afs_test_super, afs_set_super, as); | 398 | sb = sget(fs_type, afs_test_super, afs_set_super, flags, as); |
399 | if (IS_ERR(sb)) { | 399 | if (IS_ERR(sb)) { |
400 | ret = PTR_ERR(sb); | 400 | ret = PTR_ERR(sb); |
401 | afs_put_volume(vol); | 401 | afs_put_volume(vol); |
@@ -406,7 +406,6 @@ static struct dentry *afs_mount(struct file_system_type *fs_type, | |||
406 | if (!sb->s_root) { | 406 | if (!sb->s_root) { |
407 | /* initial superblock/root creation */ | 407 | /* initial superblock/root creation */ |
408 | _debug("create"); | 408 | _debug("create"); |
409 | sb->s_flags = flags; | ||
410 | ret = afs_fill_super(sb, ¶ms); | 409 | ret = afs_fill_super(sb, ¶ms); |
411 | if (ret < 0) { | 410 | if (ret < 0) { |
412 | deactivate_locked_super(sb); | 411 | deactivate_locked_super(sb); |
@@ -171,6 +171,8 @@ int notify_change(struct dentry * dentry, struct iattr * attr) | |||
171 | struct timespec now; | 171 | struct timespec now; |
172 | unsigned int ia_valid = attr->ia_valid; | 172 | unsigned int ia_valid = attr->ia_valid; |
173 | 173 | ||
174 | WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex)); | ||
175 | |||
174 | if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) { | 176 | if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) { |
175 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | 177 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
176 | return -EPERM; | 178 | return -EPERM; |
@@ -250,5 +252,4 @@ int notify_change(struct dentry * dentry, struct iattr * attr) | |||
250 | 252 | ||
251 | return error; | 253 | return error; |
252 | } | 254 | } |
253 | |||
254 | EXPORT_SYMBOL(notify_change); | 255 | EXPORT_SYMBOL(notify_change); |
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 75e5f1c8e028..e7396cfdb109 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
@@ -32,7 +32,7 @@ static long autofs4_root_ioctl(struct file *,unsigned int,unsigned long); | |||
32 | static long autofs4_root_compat_ioctl(struct file *,unsigned int,unsigned long); | 32 | static long autofs4_root_compat_ioctl(struct file *,unsigned int,unsigned long); |
33 | #endif | 33 | #endif |
34 | static int autofs4_dir_open(struct inode *inode, struct file *file); | 34 | static int autofs4_dir_open(struct inode *inode, struct file *file); |
35 | static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *); | 35 | static struct dentry *autofs4_lookup(struct inode *,struct dentry *, unsigned int); |
36 | static struct vfsmount *autofs4_d_automount(struct path *); | 36 | static struct vfsmount *autofs4_d_automount(struct path *); |
37 | static int autofs4_d_manage(struct dentry *, bool); | 37 | static int autofs4_d_manage(struct dentry *, bool); |
38 | static void autofs4_dentry_release(struct dentry *); | 38 | static void autofs4_dentry_release(struct dentry *); |
@@ -458,7 +458,7 @@ int autofs4_d_manage(struct dentry *dentry, bool rcu_walk) | |||
458 | } | 458 | } |
459 | 459 | ||
460 | /* Lookups in the root directory */ | 460 | /* Lookups in the root directory */ |
461 | static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | 461 | static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) |
462 | { | 462 | { |
463 | struct autofs_sb_info *sbi; | 463 | struct autofs_sb_info *sbi; |
464 | struct autofs_info *ino; | 464 | struct autofs_info *ino; |
diff --git a/fs/bad_inode.c b/fs/bad_inode.c index 1b35d6bd06b0..b1342ffb3cf6 100644 --- a/fs/bad_inode.c +++ b/fs/bad_inode.c | |||
@@ -173,13 +173,13 @@ static const struct file_operations bad_file_ops = | |||
173 | }; | 173 | }; |
174 | 174 | ||
175 | static int bad_inode_create (struct inode *dir, struct dentry *dentry, | 175 | static int bad_inode_create (struct inode *dir, struct dentry *dentry, |
176 | umode_t mode, struct nameidata *nd) | 176 | umode_t mode, bool excl) |
177 | { | 177 | { |
178 | return -EIO; | 178 | return -EIO; |
179 | } | 179 | } |
180 | 180 | ||
181 | static struct dentry *bad_inode_lookup(struct inode *dir, | 181 | static struct dentry *bad_inode_lookup(struct inode *dir, |
182 | struct dentry *dentry, struct nameidata *nd) | 182 | struct dentry *dentry, unsigned int flags) |
183 | { | 183 | { |
184 | return ERR_PTR(-EIO); | 184 | return ERR_PTR(-EIO); |
185 | } | 185 | } |
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index e18da23d42b5..cf7f3c67c8b7 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c | |||
@@ -34,7 +34,7 @@ static int befs_readdir(struct file *, void *, filldir_t); | |||
34 | static int befs_get_block(struct inode *, sector_t, struct buffer_head *, int); | 34 | static int befs_get_block(struct inode *, sector_t, struct buffer_head *, int); |
35 | static int befs_readpage(struct file *file, struct page *page); | 35 | static int befs_readpage(struct file *file, struct page *page); |
36 | static sector_t befs_bmap(struct address_space *mapping, sector_t block); | 36 | static sector_t befs_bmap(struct address_space *mapping, sector_t block); |
37 | static struct dentry *befs_lookup(struct inode *, struct dentry *, struct nameidata *); | 37 | static struct dentry *befs_lookup(struct inode *, struct dentry *, unsigned int); |
38 | static struct inode *befs_iget(struct super_block *, unsigned long); | 38 | static struct inode *befs_iget(struct super_block *, unsigned long); |
39 | static struct inode *befs_alloc_inode(struct super_block *sb); | 39 | static struct inode *befs_alloc_inode(struct super_block *sb); |
40 | static void befs_destroy_inode(struct inode *inode); | 40 | static void befs_destroy_inode(struct inode *inode); |
@@ -159,7 +159,7 @@ befs_get_block(struct inode *inode, sector_t block, | |||
159 | } | 159 | } |
160 | 160 | ||
161 | static struct dentry * | 161 | static struct dentry * |
162 | befs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | 162 | befs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) |
163 | { | 163 | { |
164 | struct inode *inode = NULL; | 164 | struct inode *inode = NULL; |
165 | struct super_block *sb = dir->i_sb; | 165 | struct super_block *sb = dir->i_sb; |
diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c index d12c7966db27..2785ef91191a 100644 --- a/fs/bfs/dir.c +++ b/fs/bfs/dir.c | |||
@@ -85,7 +85,7 @@ const struct file_operations bfs_dir_operations = { | |||
85 | extern void dump_imap(const char *, struct super_block *); | 85 | extern void dump_imap(const char *, struct super_block *); |
86 | 86 | ||
87 | static int bfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 87 | static int bfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
88 | struct nameidata *nd) | 88 | bool excl) |
89 | { | 89 | { |
90 | int err; | 90 | int err; |
91 | struct inode *inode; | 91 | struct inode *inode; |
@@ -133,7 +133,7 @@ static int bfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | |||
133 | } | 133 | } |
134 | 134 | ||
135 | static struct dentry *bfs_lookup(struct inode *dir, struct dentry *dentry, | 135 | static struct dentry *bfs_lookup(struct inode *dir, struct dentry *dentry, |
136 | struct nameidata *nd) | 136 | unsigned int flags) |
137 | { | 137 | { |
138 | struct inode *inode = NULL; | 138 | struct inode *inode = NULL; |
139 | struct buffer_head *bh; | 139 | struct buffer_head *bh; |
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 7301cdb4b2cb..a383c18e74e8 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c | |||
@@ -301,10 +301,14 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info, | |||
301 | goto out; | 301 | goto out; |
302 | 302 | ||
303 | eb = path->nodes[level]; | 303 | eb = path->nodes[level]; |
304 | if (!eb) { | 304 | while (!eb) { |
305 | WARN_ON(1); | 305 | if (!level) { |
306 | ret = 1; | 306 | WARN_ON(1); |
307 | goto out; | 307 | ret = 1; |
308 | goto out; | ||
309 | } | ||
310 | level--; | ||
311 | eb = path->nodes[level]; | ||
308 | } | 312 | } |
309 | 313 | ||
310 | ret = add_all_parents(root, path, parents, level, &ref->key_for_search, | 314 | ret = add_all_parents(root, path, parents, level, &ref->key_for_search, |
@@ -835,6 +839,7 @@ again: | |||
835 | } | 839 | } |
836 | ret = __add_delayed_refs(head, delayed_ref_seq, | 840 | ret = __add_delayed_refs(head, delayed_ref_seq, |
837 | &prefs_delayed); | 841 | &prefs_delayed); |
842 | mutex_unlock(&head->mutex); | ||
838 | if (ret) { | 843 | if (ret) { |
839 | spin_unlock(&delayed_refs->lock); | 844 | spin_unlock(&delayed_refs->lock); |
840 | goto out; | 845 | goto out; |
@@ -928,8 +933,6 @@ again: | |||
928 | } | 933 | } |
929 | 934 | ||
930 | out: | 935 | out: |
931 | if (head) | ||
932 | mutex_unlock(&head->mutex); | ||
933 | btrfs_free_path(path); | 936 | btrfs_free_path(path); |
934 | while (!list_empty(&prefs)) { | 937 | while (!list_empty(&prefs)) { |
935 | ref = list_first_entry(&prefs, struct __prelim_ref, list); | 938 | ref = list_first_entry(&prefs, struct __prelim_ref, list); |
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 15cbc2bf4ff0..8206b3900587 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -1024,11 +1024,18 @@ __tree_mod_log_oldest_root(struct btrfs_fs_info *fs_info, | |||
1024 | if (!looped && !tm) | 1024 | if (!looped && !tm) |
1025 | return 0; | 1025 | return 0; |
1026 | /* | 1026 | /* |
1027 | * we must have key remove operations in the log before the | 1027 | * if there are no tree operation for the oldest root, we simply |
1028 | * replace operation. | 1028 | * return it. this should only happen if that (old) root is at |
1029 | * level 0. | ||
1029 | */ | 1030 | */ |
1030 | BUG_ON(!tm); | 1031 | if (!tm) |
1032 | break; | ||
1031 | 1033 | ||
1034 | /* | ||
1035 | * if there's an operation that's not a root replacement, we | ||
1036 | * found the oldest version of our root. normally, we'll find a | ||
1037 | * MOD_LOG_KEY_REMOVE_WHILE_FREEING operation here. | ||
1038 | */ | ||
1032 | if (tm->op != MOD_LOG_ROOT_REPLACE) | 1039 | if (tm->op != MOD_LOG_ROOT_REPLACE) |
1033 | break; | 1040 | break; |
1034 | 1041 | ||
@@ -1087,11 +1094,7 @@ __tree_mod_log_rewind(struct extent_buffer *eb, u64 time_seq, | |||
1087 | tm->generation); | 1094 | tm->generation); |
1088 | break; | 1095 | break; |
1089 | case MOD_LOG_KEY_ADD: | 1096 | case MOD_LOG_KEY_ADD: |
1090 | if (tm->slot != n - 1) { | 1097 | /* if a move operation is needed it's in the log */ |
1091 | o_dst = btrfs_node_key_ptr_offset(tm->slot); | ||
1092 | o_src = btrfs_node_key_ptr_offset(tm->slot + 1); | ||
1093 | memmove_extent_buffer(eb, o_dst, o_src, p_size); | ||
1094 | } | ||
1095 | n--; | 1098 | n--; |
1096 | break; | 1099 | break; |
1097 | case MOD_LOG_MOVE_KEYS: | 1100 | case MOD_LOG_MOVE_KEYS: |
@@ -1192,16 +1195,8 @@ get_old_root(struct btrfs_root *root, u64 time_seq) | |||
1192 | } | 1195 | } |
1193 | 1196 | ||
1194 | tm = tree_mod_log_search(root->fs_info, logical, time_seq); | 1197 | tm = tree_mod_log_search(root->fs_info, logical, time_seq); |
1195 | /* | ||
1196 | * there was an item in the log when __tree_mod_log_oldest_root | ||
1197 | * returned. this one must not go away, because the time_seq passed to | ||
1198 | * us must be blocking its removal. | ||
1199 | */ | ||
1200 | BUG_ON(!tm); | ||
1201 | |||
1202 | if (old_root) | 1198 | if (old_root) |
1203 | eb = alloc_dummy_extent_buffer(tm->index << PAGE_CACHE_SHIFT, | 1199 | eb = alloc_dummy_extent_buffer(logical, root->nodesize); |
1204 | root->nodesize); | ||
1205 | else | 1200 | else |
1206 | eb = btrfs_clone_extent_buffer(root->node); | 1201 | eb = btrfs_clone_extent_buffer(root->node); |
1207 | btrfs_tree_read_unlock(root->node); | 1202 | btrfs_tree_read_unlock(root->node); |
@@ -1216,7 +1211,10 @@ get_old_root(struct btrfs_root *root, u64 time_seq) | |||
1216 | btrfs_set_header_level(eb, old_root->level); | 1211 | btrfs_set_header_level(eb, old_root->level); |
1217 | btrfs_set_header_generation(eb, old_generation); | 1212 | btrfs_set_header_generation(eb, old_generation); |
1218 | } | 1213 | } |
1219 | __tree_mod_log_rewind(eb, time_seq, tm); | 1214 | if (tm) |
1215 | __tree_mod_log_rewind(eb, time_seq, tm); | ||
1216 | else | ||
1217 | WARN_ON(btrfs_header_level(eb) != 0); | ||
1220 | extent_buffer_get(eb); | 1218 | extent_buffer_get(eb); |
1221 | 1219 | ||
1222 | return eb; | 1220 | return eb; |
@@ -2995,7 +2993,7 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans, | |||
2995 | static void insert_ptr(struct btrfs_trans_handle *trans, | 2993 | static void insert_ptr(struct btrfs_trans_handle *trans, |
2996 | struct btrfs_root *root, struct btrfs_path *path, | 2994 | struct btrfs_root *root, struct btrfs_path *path, |
2997 | struct btrfs_disk_key *key, u64 bytenr, | 2995 | struct btrfs_disk_key *key, u64 bytenr, |
2998 | int slot, int level, int tree_mod_log) | 2996 | int slot, int level) |
2999 | { | 2997 | { |
3000 | struct extent_buffer *lower; | 2998 | struct extent_buffer *lower; |
3001 | int nritems; | 2999 | int nritems; |
@@ -3008,7 +3006,7 @@ static void insert_ptr(struct btrfs_trans_handle *trans, | |||
3008 | BUG_ON(slot > nritems); | 3006 | BUG_ON(slot > nritems); |
3009 | BUG_ON(nritems == BTRFS_NODEPTRS_PER_BLOCK(root)); | 3007 | BUG_ON(nritems == BTRFS_NODEPTRS_PER_BLOCK(root)); |
3010 | if (slot != nritems) { | 3008 | if (slot != nritems) { |
3011 | if (tree_mod_log && level) | 3009 | if (level) |
3012 | tree_mod_log_eb_move(root->fs_info, lower, slot + 1, | 3010 | tree_mod_log_eb_move(root->fs_info, lower, slot + 1, |
3013 | slot, nritems - slot); | 3011 | slot, nritems - slot); |
3014 | memmove_extent_buffer(lower, | 3012 | memmove_extent_buffer(lower, |
@@ -3016,7 +3014,7 @@ static void insert_ptr(struct btrfs_trans_handle *trans, | |||
3016 | btrfs_node_key_ptr_offset(slot), | 3014 | btrfs_node_key_ptr_offset(slot), |
3017 | (nritems - slot) * sizeof(struct btrfs_key_ptr)); | 3015 | (nritems - slot) * sizeof(struct btrfs_key_ptr)); |
3018 | } | 3016 | } |
3019 | if (tree_mod_log && level) { | 3017 | if (level) { |
3020 | ret = tree_mod_log_insert_key(root->fs_info, lower, slot, | 3018 | ret = tree_mod_log_insert_key(root->fs_info, lower, slot, |
3021 | MOD_LOG_KEY_ADD); | 3019 | MOD_LOG_KEY_ADD); |
3022 | BUG_ON(ret < 0); | 3020 | BUG_ON(ret < 0); |
@@ -3104,7 +3102,7 @@ static noinline int split_node(struct btrfs_trans_handle *trans, | |||
3104 | btrfs_mark_buffer_dirty(split); | 3102 | btrfs_mark_buffer_dirty(split); |
3105 | 3103 | ||
3106 | insert_ptr(trans, root, path, &disk_key, split->start, | 3104 | insert_ptr(trans, root, path, &disk_key, split->start, |
3107 | path->slots[level + 1] + 1, level + 1, 1); | 3105 | path->slots[level + 1] + 1, level + 1); |
3108 | 3106 | ||
3109 | if (path->slots[level] >= mid) { | 3107 | if (path->slots[level] >= mid) { |
3110 | path->slots[level] -= mid; | 3108 | path->slots[level] -= mid; |
@@ -3641,7 +3639,7 @@ static noinline void copy_for_split(struct btrfs_trans_handle *trans, | |||
3641 | btrfs_set_header_nritems(l, mid); | 3639 | btrfs_set_header_nritems(l, mid); |
3642 | btrfs_item_key(right, &disk_key, 0); | 3640 | btrfs_item_key(right, &disk_key, 0); |
3643 | insert_ptr(trans, root, path, &disk_key, right->start, | 3641 | insert_ptr(trans, root, path, &disk_key, right->start, |
3644 | path->slots[1] + 1, 1, 0); | 3642 | path->slots[1] + 1, 1); |
3645 | 3643 | ||
3646 | btrfs_mark_buffer_dirty(right); | 3644 | btrfs_mark_buffer_dirty(right); |
3647 | btrfs_mark_buffer_dirty(l); | 3645 | btrfs_mark_buffer_dirty(l); |
@@ -3848,7 +3846,7 @@ again: | |||
3848 | if (mid <= slot) { | 3846 | if (mid <= slot) { |
3849 | btrfs_set_header_nritems(right, 0); | 3847 | btrfs_set_header_nritems(right, 0); |
3850 | insert_ptr(trans, root, path, &disk_key, right->start, | 3848 | insert_ptr(trans, root, path, &disk_key, right->start, |
3851 | path->slots[1] + 1, 1, 0); | 3849 | path->slots[1] + 1, 1); |
3852 | btrfs_tree_unlock(path->nodes[0]); | 3850 | btrfs_tree_unlock(path->nodes[0]); |
3853 | free_extent_buffer(path->nodes[0]); | 3851 | free_extent_buffer(path->nodes[0]); |
3854 | path->nodes[0] = right; | 3852 | path->nodes[0] = right; |
@@ -3857,7 +3855,7 @@ again: | |||
3857 | } else { | 3855 | } else { |
3858 | btrfs_set_header_nritems(right, 0); | 3856 | btrfs_set_header_nritems(right, 0); |
3859 | insert_ptr(trans, root, path, &disk_key, right->start, | 3857 | insert_ptr(trans, root, path, &disk_key, right->start, |
3860 | path->slots[1], 1, 0); | 3858 | path->slots[1], 1); |
3861 | btrfs_tree_unlock(path->nodes[0]); | 3859 | btrfs_tree_unlock(path->nodes[0]); |
3862 | free_extent_buffer(path->nodes[0]); | 3860 | free_extent_buffer(path->nodes[0]); |
3863 | path->nodes[0] = right; | 3861 | path->nodes[0] = right; |
@@ -5121,6 +5119,18 @@ again: | |||
5121 | 5119 | ||
5122 | if (!path->skip_locking) { | 5120 | if (!path->skip_locking) { |
5123 | ret = btrfs_try_tree_read_lock(next); | 5121 | ret = btrfs_try_tree_read_lock(next); |
5122 | if (!ret && time_seq) { | ||
5123 | /* | ||
5124 | * If we don't get the lock, we may be racing | ||
5125 | * with push_leaf_left, holding that lock while | ||
5126 | * itself waiting for the leaf we've currently | ||
5127 | * locked. To solve this situation, we give up | ||
5128 | * on our lock and cycle. | ||
5129 | */ | ||
5130 | btrfs_release_path(path); | ||
5131 | cond_resched(); | ||
5132 | goto again; | ||
5133 | } | ||
5124 | if (!ret) { | 5134 | if (!ret) { |
5125 | btrfs_set_path_blocking(path); | 5135 | btrfs_set_path_blocking(path); |
5126 | btrfs_tree_read_lock(next); | 5136 | btrfs_tree_read_lock(next); |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 7b845ff4af99..2936ca49b3b4 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -2354,12 +2354,17 @@ retry_root_backup: | |||
2354 | BTRFS_CSUM_TREE_OBJECTID, csum_root); | 2354 | BTRFS_CSUM_TREE_OBJECTID, csum_root); |
2355 | if (ret) | 2355 | if (ret) |
2356 | goto recovery_tree_root; | 2356 | goto recovery_tree_root; |
2357 | |||
2358 | csum_root->track_dirty = 1; | 2357 | csum_root->track_dirty = 1; |
2359 | 2358 | ||
2360 | fs_info->generation = generation; | 2359 | fs_info->generation = generation; |
2361 | fs_info->last_trans_committed = generation; | 2360 | fs_info->last_trans_committed = generation; |
2362 | 2361 | ||
2362 | ret = btrfs_recover_balance(fs_info); | ||
2363 | if (ret) { | ||
2364 | printk(KERN_WARNING "btrfs: failed to recover balance\n"); | ||
2365 | goto fail_block_groups; | ||
2366 | } | ||
2367 | |||
2363 | ret = btrfs_init_dev_stats(fs_info); | 2368 | ret = btrfs_init_dev_stats(fs_info); |
2364 | if (ret) { | 2369 | if (ret) { |
2365 | printk(KERN_ERR "btrfs: failed to init dev_stats: %d\n", | 2370 | printk(KERN_ERR "btrfs: failed to init dev_stats: %d\n", |
@@ -2485,20 +2490,23 @@ retry_root_backup: | |||
2485 | goto fail_trans_kthread; | 2490 | goto fail_trans_kthread; |
2486 | } | 2491 | } |
2487 | 2492 | ||
2488 | if (!(sb->s_flags & MS_RDONLY)) { | 2493 | if (sb->s_flags & MS_RDONLY) |
2489 | down_read(&fs_info->cleanup_work_sem); | 2494 | return 0; |
2490 | err = btrfs_orphan_cleanup(fs_info->fs_root); | ||
2491 | if (!err) | ||
2492 | err = btrfs_orphan_cleanup(fs_info->tree_root); | ||
2493 | up_read(&fs_info->cleanup_work_sem); | ||
2494 | 2495 | ||
2495 | if (!err) | 2496 | down_read(&fs_info->cleanup_work_sem); |
2496 | err = btrfs_recover_balance(fs_info->tree_root); | 2497 | if ((ret = btrfs_orphan_cleanup(fs_info->fs_root)) || |
2498 | (ret = btrfs_orphan_cleanup(fs_info->tree_root))) { | ||
2499 | up_read(&fs_info->cleanup_work_sem); | ||
2500 | close_ctree(tree_root); | ||
2501 | return ret; | ||
2502 | } | ||
2503 | up_read(&fs_info->cleanup_work_sem); | ||
2497 | 2504 | ||
2498 | if (err) { | 2505 | ret = btrfs_resume_balance_async(fs_info); |
2499 | close_ctree(tree_root); | 2506 | if (ret) { |
2500 | return err; | 2507 | printk(KERN_WARNING "btrfs: failed to resume balance\n"); |
2501 | } | 2508 | close_ctree(tree_root); |
2509 | return ret; | ||
2502 | } | 2510 | } |
2503 | 2511 | ||
2504 | return 0; | 2512 | return 0; |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 4b5a1e1bdefb..6e1d36702ff7 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -2347,12 +2347,10 @@ next: | |||
2347 | return count; | 2347 | return count; |
2348 | } | 2348 | } |
2349 | 2349 | ||
2350 | |||
2351 | static void wait_for_more_refs(struct btrfs_delayed_ref_root *delayed_refs, | 2350 | static void wait_for_more_refs(struct btrfs_delayed_ref_root *delayed_refs, |
2352 | unsigned long num_refs) | 2351 | unsigned long num_refs, |
2352 | struct list_head *first_seq) | ||
2353 | { | 2353 | { |
2354 | struct list_head *first_seq = delayed_refs->seq_head.next; | ||
2355 | |||
2356 | spin_unlock(&delayed_refs->lock); | 2354 | spin_unlock(&delayed_refs->lock); |
2357 | pr_debug("waiting for more refs (num %ld, first %p)\n", | 2355 | pr_debug("waiting for more refs (num %ld, first %p)\n", |
2358 | num_refs, first_seq); | 2356 | num_refs, first_seq); |
@@ -2381,6 +2379,7 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, | |||
2381 | struct btrfs_delayed_ref_root *delayed_refs; | 2379 | struct btrfs_delayed_ref_root *delayed_refs; |
2382 | struct btrfs_delayed_ref_node *ref; | 2380 | struct btrfs_delayed_ref_node *ref; |
2383 | struct list_head cluster; | 2381 | struct list_head cluster; |
2382 | struct list_head *first_seq = NULL; | ||
2384 | int ret; | 2383 | int ret; |
2385 | u64 delayed_start; | 2384 | u64 delayed_start; |
2386 | int run_all = count == (unsigned long)-1; | 2385 | int run_all = count == (unsigned long)-1; |
@@ -2436,8 +2435,10 @@ again: | |||
2436 | */ | 2435 | */ |
2437 | consider_waiting = 1; | 2436 | consider_waiting = 1; |
2438 | num_refs = delayed_refs->num_entries; | 2437 | num_refs = delayed_refs->num_entries; |
2438 | first_seq = root->fs_info->tree_mod_seq_list.next; | ||
2439 | } else { | 2439 | } else { |
2440 | wait_for_more_refs(delayed_refs, num_refs); | 2440 | wait_for_more_refs(delayed_refs, |
2441 | num_refs, first_seq); | ||
2441 | /* | 2442 | /* |
2442 | * after waiting, things have changed. we | 2443 | * after waiting, things have changed. we |
2443 | * dropped the lock and someone else might have | 2444 | * dropped the lock and someone else might have |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index aaa12c1eb348..01c21b6c6d43 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -3324,6 +3324,7 @@ static int extent_write_cache_pages(struct extent_io_tree *tree, | |||
3324 | writepage_t writepage, void *data, | 3324 | writepage_t writepage, void *data, |
3325 | void (*flush_fn)(void *)) | 3325 | void (*flush_fn)(void *)) |
3326 | { | 3326 | { |
3327 | struct inode *inode = mapping->host; | ||
3327 | int ret = 0; | 3328 | int ret = 0; |
3328 | int done = 0; | 3329 | int done = 0; |
3329 | int nr_to_write_done = 0; | 3330 | int nr_to_write_done = 0; |
@@ -3334,6 +3335,18 @@ static int extent_write_cache_pages(struct extent_io_tree *tree, | |||
3334 | int scanned = 0; | 3335 | int scanned = 0; |
3335 | int tag; | 3336 | int tag; |
3336 | 3337 | ||
3338 | /* | ||
3339 | * We have to hold onto the inode so that ordered extents can do their | ||
3340 | * work when the IO finishes. The alternative to this is failing to add | ||
3341 | * an ordered extent if the igrab() fails there and that is a huge pain | ||
3342 | * to deal with, so instead just hold onto the inode throughout the | ||
3343 | * writepages operation. If it fails here we are freeing up the inode | ||
3344 | * anyway and we'd rather not waste our time writing out stuff that is | ||
3345 | * going to be truncated anyway. | ||
3346 | */ | ||
3347 | if (!igrab(inode)) | ||
3348 | return 0; | ||
3349 | |||
3337 | pagevec_init(&pvec, 0); | 3350 | pagevec_init(&pvec, 0); |
3338 | if (wbc->range_cyclic) { | 3351 | if (wbc->range_cyclic) { |
3339 | index = mapping->writeback_index; /* Start from prev offset */ | 3352 | index = mapping->writeback_index; /* Start from prev offset */ |
@@ -3428,6 +3441,7 @@ retry: | |||
3428 | index = 0; | 3441 | index = 0; |
3429 | goto retry; | 3442 | goto retry; |
3430 | } | 3443 | } |
3444 | btrfs_add_delayed_iput(inode); | ||
3431 | return ret; | 3445 | return ret; |
3432 | } | 3446 | } |
3433 | 3447 | ||
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 70dc8ca73e25..9aa01ec2138d 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -1334,7 +1334,6 @@ static ssize_t __btrfs_direct_write(struct kiocb *iocb, | |||
1334 | loff_t *ppos, size_t count, size_t ocount) | 1334 | loff_t *ppos, size_t count, size_t ocount) |
1335 | { | 1335 | { |
1336 | struct file *file = iocb->ki_filp; | 1336 | struct file *file = iocb->ki_filp; |
1337 | struct inode *inode = fdentry(file)->d_inode; | ||
1338 | struct iov_iter i; | 1337 | struct iov_iter i; |
1339 | ssize_t written; | 1338 | ssize_t written; |
1340 | ssize_t written_buffered; | 1339 | ssize_t written_buffered; |
@@ -1344,18 +1343,6 @@ static ssize_t __btrfs_direct_write(struct kiocb *iocb, | |||
1344 | written = generic_file_direct_write(iocb, iov, &nr_segs, pos, ppos, | 1343 | written = generic_file_direct_write(iocb, iov, &nr_segs, pos, ppos, |
1345 | count, ocount); | 1344 | count, ocount); |
1346 | 1345 | ||
1347 | /* | ||
1348 | * the generic O_DIRECT will update in-memory i_size after the | ||
1349 | * DIOs are done. But our endio handlers that update the on | ||
1350 | * disk i_size never update past the in memory i_size. So we | ||
1351 | * need one more update here to catch any additions to the | ||
1352 | * file | ||
1353 | */ | ||
1354 | if (inode->i_size != BTRFS_I(inode)->disk_i_size) { | ||
1355 | btrfs_ordered_update_i_size(inode, inode->i_size, NULL); | ||
1356 | mark_inode_dirty(inode); | ||
1357 | } | ||
1358 | |||
1359 | if (written < 0 || written == count) | 1346 | if (written < 0 || written == count) |
1360 | return written; | 1347 | return written; |
1361 | 1348 | ||
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index 81296c57405a..6c4e2baa9290 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
@@ -1543,29 +1543,26 @@ again: | |||
1543 | end = bitmap_info->offset + (u64)(BITS_PER_BITMAP * ctl->unit) - 1; | 1543 | end = bitmap_info->offset + (u64)(BITS_PER_BITMAP * ctl->unit) - 1; |
1544 | 1544 | ||
1545 | /* | 1545 | /* |
1546 | * XXX - this can go away after a few releases. | 1546 | * We need to search for bits in this bitmap. We could only cover some |
1547 | * | 1547 | * of the extent in this bitmap thanks to how we add space, so we need |
1548 | * since the only user of btrfs_remove_free_space is the tree logging | 1548 | * to search for as much as it as we can and clear that amount, and then |
1549 | * stuff, and the only way to test that is under crash conditions, we | 1549 | * go searching for the next bit. |
1550 | * want to have this debug stuff here just in case somethings not | ||
1551 | * working. Search the bitmap for the space we are trying to use to | ||
1552 | * make sure its actually there. If its not there then we need to stop | ||
1553 | * because something has gone wrong. | ||
1554 | */ | 1550 | */ |
1555 | search_start = *offset; | 1551 | search_start = *offset; |
1556 | search_bytes = *bytes; | 1552 | search_bytes = ctl->unit; |
1557 | search_bytes = min(search_bytes, end - search_start + 1); | 1553 | search_bytes = min(search_bytes, end - search_start + 1); |
1558 | ret = search_bitmap(ctl, bitmap_info, &search_start, &search_bytes); | 1554 | ret = search_bitmap(ctl, bitmap_info, &search_start, &search_bytes); |
1559 | BUG_ON(ret < 0 || search_start != *offset); | 1555 | BUG_ON(ret < 0 || search_start != *offset); |
1560 | 1556 | ||
1561 | if (*offset > bitmap_info->offset && *offset + *bytes > end) { | 1557 | /* We may have found more bits than what we need */ |
1562 | bitmap_clear_bits(ctl, bitmap_info, *offset, end - *offset + 1); | 1558 | search_bytes = min(search_bytes, *bytes); |
1563 | *bytes -= end - *offset + 1; | 1559 | |
1564 | *offset = end + 1; | 1560 | /* Cannot clear past the end of the bitmap */ |
1565 | } else if (*offset >= bitmap_info->offset && *offset + *bytes <= end) { | 1561 | search_bytes = min(search_bytes, end - search_start + 1); |
1566 | bitmap_clear_bits(ctl, bitmap_info, *offset, *bytes); | 1562 | |
1567 | *bytes = 0; | 1563 | bitmap_clear_bits(ctl, bitmap_info, search_start, search_bytes); |
1568 | } | 1564 | *offset += search_bytes; |
1565 | *bytes -= search_bytes; | ||
1569 | 1566 | ||
1570 | if (*bytes) { | 1567 | if (*bytes) { |
1571 | struct rb_node *next = rb_next(&bitmap_info->offset_index); | 1568 | struct rb_node *next = rb_next(&bitmap_info->offset_index); |
@@ -1596,7 +1593,7 @@ again: | |||
1596 | * everything over again. | 1593 | * everything over again. |
1597 | */ | 1594 | */ |
1598 | search_start = *offset; | 1595 | search_start = *offset; |
1599 | search_bytes = *bytes; | 1596 | search_bytes = ctl->unit; |
1600 | ret = search_bitmap(ctl, bitmap_info, &search_start, | 1597 | ret = search_bitmap(ctl, bitmap_info, &search_start, |
1601 | &search_bytes); | 1598 | &search_bytes); |
1602 | if (ret < 0 || search_start != *offset) | 1599 | if (ret < 0 || search_start != *offset) |
@@ -1879,12 +1876,14 @@ int btrfs_remove_free_space(struct btrfs_block_group_cache *block_group, | |||
1879 | { | 1876 | { |
1880 | struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; | 1877 | struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; |
1881 | struct btrfs_free_space *info; | 1878 | struct btrfs_free_space *info; |
1882 | struct btrfs_free_space *next_info = NULL; | ||
1883 | int ret = 0; | 1879 | int ret = 0; |
1884 | 1880 | ||
1885 | spin_lock(&ctl->tree_lock); | 1881 | spin_lock(&ctl->tree_lock); |
1886 | 1882 | ||
1887 | again: | 1883 | again: |
1884 | if (!bytes) | ||
1885 | goto out_lock; | ||
1886 | |||
1888 | info = tree_search_offset(ctl, offset, 0, 0); | 1887 | info = tree_search_offset(ctl, offset, 0, 0); |
1889 | if (!info) { | 1888 | if (!info) { |
1890 | /* | 1889 | /* |
@@ -1905,88 +1904,48 @@ again: | |||
1905 | } | 1904 | } |
1906 | } | 1905 | } |
1907 | 1906 | ||
1908 | if (info->bytes < bytes && rb_next(&info->offset_index)) { | 1907 | if (!info->bitmap) { |
1909 | u64 end; | ||
1910 | next_info = rb_entry(rb_next(&info->offset_index), | ||
1911 | struct btrfs_free_space, | ||
1912 | offset_index); | ||
1913 | |||
1914 | if (next_info->bitmap) | ||
1915 | end = next_info->offset + | ||
1916 | BITS_PER_BITMAP * ctl->unit - 1; | ||
1917 | else | ||
1918 | end = next_info->offset + next_info->bytes; | ||
1919 | |||
1920 | if (next_info->bytes < bytes || | ||
1921 | next_info->offset > offset || offset > end) { | ||
1922 | printk(KERN_CRIT "Found free space at %llu, size %llu," | ||
1923 | " trying to use %llu\n", | ||
1924 | (unsigned long long)info->offset, | ||
1925 | (unsigned long long)info->bytes, | ||
1926 | (unsigned long long)bytes); | ||
1927 | WARN_ON(1); | ||
1928 | ret = -EINVAL; | ||
1929 | goto out_lock; | ||
1930 | } | ||
1931 | |||
1932 | info = next_info; | ||
1933 | } | ||
1934 | |||
1935 | if (info->bytes == bytes) { | ||
1936 | unlink_free_space(ctl, info); | 1908 | unlink_free_space(ctl, info); |
1937 | if (info->bitmap) { | 1909 | if (offset == info->offset) { |
1938 | kfree(info->bitmap); | 1910 | u64 to_free = min(bytes, info->bytes); |
1939 | ctl->total_bitmaps--; | 1911 | |
1940 | } | 1912 | info->bytes -= to_free; |
1941 | kmem_cache_free(btrfs_free_space_cachep, info); | 1913 | info->offset += to_free; |
1942 | ret = 0; | 1914 | if (info->bytes) { |
1943 | goto out_lock; | 1915 | ret = link_free_space(ctl, info); |
1944 | } | 1916 | WARN_ON(ret); |
1945 | 1917 | } else { | |
1946 | if (!info->bitmap && info->offset == offset) { | 1918 | kmem_cache_free(btrfs_free_space_cachep, info); |
1947 | unlink_free_space(ctl, info); | 1919 | } |
1948 | info->offset += bytes; | ||
1949 | info->bytes -= bytes; | ||
1950 | ret = link_free_space(ctl, info); | ||
1951 | WARN_ON(ret); | ||
1952 | goto out_lock; | ||
1953 | } | ||
1954 | 1920 | ||
1955 | if (!info->bitmap && info->offset <= offset && | 1921 | offset += to_free; |
1956 | info->offset + info->bytes >= offset + bytes) { | 1922 | bytes -= to_free; |
1957 | u64 old_start = info->offset; | 1923 | goto again; |
1958 | /* | 1924 | } else { |
1959 | * we're freeing space in the middle of the info, | 1925 | u64 old_end = info->bytes + info->offset; |
1960 | * this can happen during tree log replay | ||
1961 | * | ||
1962 | * first unlink the old info and then | ||
1963 | * insert it again after the hole we're creating | ||
1964 | */ | ||
1965 | unlink_free_space(ctl, info); | ||
1966 | if (offset + bytes < info->offset + info->bytes) { | ||
1967 | u64 old_end = info->offset + info->bytes; | ||
1968 | 1926 | ||
1969 | info->offset = offset + bytes; | 1927 | info->bytes = offset - info->offset; |
1970 | info->bytes = old_end - info->offset; | ||
1971 | ret = link_free_space(ctl, info); | 1928 | ret = link_free_space(ctl, info); |
1972 | WARN_ON(ret); | 1929 | WARN_ON(ret); |
1973 | if (ret) | 1930 | if (ret) |
1974 | goto out_lock; | 1931 | goto out_lock; |
1975 | } else { | ||
1976 | /* the hole we're creating ends at the end | ||
1977 | * of the info struct, just free the info | ||
1978 | */ | ||
1979 | kmem_cache_free(btrfs_free_space_cachep, info); | ||
1980 | } | ||
1981 | spin_unlock(&ctl->tree_lock); | ||
1982 | 1932 | ||
1983 | /* step two, insert a new info struct to cover | 1933 | /* Not enough bytes in this entry to satisfy us */ |
1984 | * anything before the hole | 1934 | if (old_end < offset + bytes) { |
1985 | */ | 1935 | bytes -= old_end - offset; |
1986 | ret = btrfs_add_free_space(block_group, old_start, | 1936 | offset = old_end; |
1987 | offset - old_start); | 1937 | goto again; |
1988 | WARN_ON(ret); /* -ENOMEM */ | 1938 | } else if (old_end == offset + bytes) { |
1989 | goto out; | 1939 | /* all done */ |
1940 | goto out_lock; | ||
1941 | } | ||
1942 | spin_unlock(&ctl->tree_lock); | ||
1943 | |||
1944 | ret = btrfs_add_free_space(block_group, offset + bytes, | ||
1945 | old_end - (offset + bytes)); | ||
1946 | WARN_ON(ret); | ||
1947 | goto out; | ||
1948 | } | ||
1990 | } | 1949 | } |
1991 | 1950 | ||
1992 | ret = remove_from_bitmap(ctl, info, &offset, &bytes); | 1951 | ret = remove_from_bitmap(ctl, info, &offset, &bytes); |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index d8bb0dbc4941..fb8d671d00e6 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -3754,7 +3754,7 @@ void btrfs_evict_inode(struct inode *inode) | |||
3754 | btrfs_wait_ordered_range(inode, 0, (u64)-1); | 3754 | btrfs_wait_ordered_range(inode, 0, (u64)-1); |
3755 | 3755 | ||
3756 | if (root->fs_info->log_root_recovering) { | 3756 | if (root->fs_info->log_root_recovering) { |
3757 | BUG_ON(!test_bit(BTRFS_INODE_HAS_ORPHAN_ITEM, | 3757 | BUG_ON(test_bit(BTRFS_INODE_HAS_ORPHAN_ITEM, |
3758 | &BTRFS_I(inode)->runtime_flags)); | 3758 | &BTRFS_I(inode)->runtime_flags)); |
3759 | goto no_delete; | 3759 | goto no_delete; |
3760 | } | 3760 | } |
@@ -4247,7 +4247,7 @@ static void btrfs_dentry_release(struct dentry *dentry) | |||
4247 | } | 4247 | } |
4248 | 4248 | ||
4249 | static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry, | 4249 | static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry, |
4250 | struct nameidata *nd) | 4250 | unsigned int flags) |
4251 | { | 4251 | { |
4252 | struct dentry *ret; | 4252 | struct dentry *ret; |
4253 | 4253 | ||
@@ -4893,7 +4893,7 @@ out_unlock: | |||
4893 | } | 4893 | } |
4894 | 4894 | ||
4895 | static int btrfs_create(struct inode *dir, struct dentry *dentry, | 4895 | static int btrfs_create(struct inode *dir, struct dentry *dentry, |
4896 | umode_t mode, struct nameidata *nd) | 4896 | umode_t mode, bool excl) |
4897 | { | 4897 | { |
4898 | struct btrfs_trans_handle *trans; | 4898 | struct btrfs_trans_handle *trans; |
4899 | struct btrfs_root *root = BTRFS_I(dir)->root; | 4899 | struct btrfs_root *root = BTRFS_I(dir)->root; |
@@ -5876,8 +5876,17 @@ map: | |||
5876 | bh_result->b_size = len; | 5876 | bh_result->b_size = len; |
5877 | bh_result->b_bdev = em->bdev; | 5877 | bh_result->b_bdev = em->bdev; |
5878 | set_buffer_mapped(bh_result); | 5878 | set_buffer_mapped(bh_result); |
5879 | if (create && !test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) | 5879 | if (create) { |
5880 | set_buffer_new(bh_result); | 5880 | if (!test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) |
5881 | set_buffer_new(bh_result); | ||
5882 | |||
5883 | /* | ||
5884 | * Need to update the i_size under the extent lock so buffered | ||
5885 | * readers will get the updated i_size when we unlock. | ||
5886 | */ | ||
5887 | if (start + len > i_size_read(inode)) | ||
5888 | i_size_write(inode, start + len); | ||
5889 | } | ||
5881 | 5890 | ||
5882 | free_extent_map(em); | 5891 | free_extent_map(em); |
5883 | 5892 | ||
@@ -6360,12 +6369,48 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, | |||
6360 | */ | 6369 | */ |
6361 | ordered = btrfs_lookup_ordered_range(inode, lockstart, | 6370 | ordered = btrfs_lookup_ordered_range(inode, lockstart, |
6362 | lockend - lockstart + 1); | 6371 | lockend - lockstart + 1); |
6363 | if (!ordered) | 6372 | |
6373 | /* | ||
6374 | * We need to make sure there are no buffered pages in this | ||
6375 | * range either, we could have raced between the invalidate in | ||
6376 | * generic_file_direct_write and locking the extent. The | ||
6377 | * invalidate needs to happen so that reads after a write do not | ||
6378 | * get stale data. | ||
6379 | */ | ||
6380 | if (!ordered && (!writing || | ||
6381 | !test_range_bit(&BTRFS_I(inode)->io_tree, | ||
6382 | lockstart, lockend, EXTENT_UPTODATE, 0, | ||
6383 | cached_state))) | ||
6364 | break; | 6384 | break; |
6385 | |||
6365 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, lockstart, lockend, | 6386 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, lockstart, lockend, |
6366 | &cached_state, GFP_NOFS); | 6387 | &cached_state, GFP_NOFS); |
6367 | btrfs_start_ordered_extent(inode, ordered, 1); | 6388 | |
6368 | btrfs_put_ordered_extent(ordered); | 6389 | if (ordered) { |
6390 | btrfs_start_ordered_extent(inode, ordered, 1); | ||
6391 | btrfs_put_ordered_extent(ordered); | ||
6392 | } else { | ||
6393 | /* Screw you mmap */ | ||
6394 | ret = filemap_write_and_wait_range(file->f_mapping, | ||
6395 | lockstart, | ||
6396 | lockend); | ||
6397 | if (ret) | ||
6398 | goto out; | ||
6399 | |||
6400 | /* | ||
6401 | * If we found a page that couldn't be invalidated just | ||
6402 | * fall back to buffered. | ||
6403 | */ | ||
6404 | ret = invalidate_inode_pages2_range(file->f_mapping, | ||
6405 | lockstart >> PAGE_CACHE_SHIFT, | ||
6406 | lockend >> PAGE_CACHE_SHIFT); | ||
6407 | if (ret) { | ||
6408 | if (ret == -EBUSY) | ||
6409 | ret = 0; | ||
6410 | goto out; | ||
6411 | } | ||
6412 | } | ||
6413 | |||
6369 | cond_resched(); | 6414 | cond_resched(); |
6370 | } | 6415 | } |
6371 | 6416 | ||
@@ -6942,7 +6987,7 @@ void btrfs_destroy_inode(struct inode *inode) | |||
6942 | struct btrfs_ordered_extent *ordered; | 6987 | struct btrfs_ordered_extent *ordered; |
6943 | struct btrfs_root *root = BTRFS_I(inode)->root; | 6988 | struct btrfs_root *root = BTRFS_I(inode)->root; |
6944 | 6989 | ||
6945 | WARN_ON(!list_empty(&inode->i_dentry)); | 6990 | WARN_ON(!hlist_empty(&inode->i_dentry)); |
6946 | WARN_ON(inode->i_data.nrpages); | 6991 | WARN_ON(inode->i_data.nrpages); |
6947 | WARN_ON(BTRFS_I(inode)->outstanding_extents); | 6992 | WARN_ON(BTRFS_I(inode)->outstanding_extents); |
6948 | WARN_ON(BTRFS_I(inode)->reserved_extents); | 6993 | WARN_ON(BTRFS_I(inode)->reserved_extents); |
diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h index 497c530724cf..e440aa653c30 100644 --- a/fs/btrfs/ioctl.h +++ b/fs/btrfs/ioctl.h | |||
@@ -339,7 +339,7 @@ struct btrfs_ioctl_get_dev_stats { | |||
339 | #define BTRFS_IOC_WAIT_SYNC _IOW(BTRFS_IOCTL_MAGIC, 22, __u64) | 339 | #define BTRFS_IOC_WAIT_SYNC _IOW(BTRFS_IOCTL_MAGIC, 22, __u64) |
340 | #define BTRFS_IOC_SNAP_CREATE_V2 _IOW(BTRFS_IOCTL_MAGIC, 23, \ | 340 | #define BTRFS_IOC_SNAP_CREATE_V2 _IOW(BTRFS_IOCTL_MAGIC, 23, \ |
341 | struct btrfs_ioctl_vol_args_v2) | 341 | struct btrfs_ioctl_vol_args_v2) |
342 | #define BTRFS_IOC_SUBVOL_GETFLAGS _IOW(BTRFS_IOCTL_MAGIC, 25, __u64) | 342 | #define BTRFS_IOC_SUBVOL_GETFLAGS _IOR(BTRFS_IOCTL_MAGIC, 25, __u64) |
343 | #define BTRFS_IOC_SUBVOL_SETFLAGS _IOW(BTRFS_IOCTL_MAGIC, 26, __u64) | 343 | #define BTRFS_IOC_SUBVOL_SETFLAGS _IOW(BTRFS_IOCTL_MAGIC, 26, __u64) |
344 | #define BTRFS_IOC_SCRUB _IOWR(BTRFS_IOCTL_MAGIC, 27, \ | 344 | #define BTRFS_IOC_SCRUB _IOWR(BTRFS_IOCTL_MAGIC, 27, \ |
345 | struct btrfs_ioctl_scrub_args) | 345 | struct btrfs_ioctl_scrub_args) |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 0eb9a4da069e..b19d75567728 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -1068,7 +1068,8 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
1068 | } | 1068 | } |
1069 | 1069 | ||
1070 | bdev = fs_devices->latest_bdev; | 1070 | bdev = fs_devices->latest_bdev; |
1071 | s = sget(fs_type, btrfs_test_super, btrfs_set_super, fs_info); | 1071 | s = sget(fs_type, btrfs_test_super, btrfs_set_super, flags | MS_NOSEC, |
1072 | fs_info); | ||
1072 | if (IS_ERR(s)) { | 1073 | if (IS_ERR(s)) { |
1073 | error = PTR_ERR(s); | 1074 | error = PTR_ERR(s); |
1074 | goto error_close_devices; | 1075 | goto error_close_devices; |
@@ -1082,7 +1083,6 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
1082 | } else { | 1083 | } else { |
1083 | char b[BDEVNAME_SIZE]; | 1084 | char b[BDEVNAME_SIZE]; |
1084 | 1085 | ||
1085 | s->s_flags = flags | MS_NOSEC; | ||
1086 | strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); | 1086 | strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); |
1087 | btrfs_sb(s)->bdev_holder = fs_type; | 1087 | btrfs_sb(s)->bdev_holder = fs_type; |
1088 | error = btrfs_fill_super(s, fs_devices, data, | 1088 | error = btrfs_fill_super(s, fs_devices, data, |
@@ -1187,6 +1187,10 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) | |||
1187 | if (ret) | 1187 | if (ret) |
1188 | goto restore; | 1188 | goto restore; |
1189 | 1189 | ||
1190 | ret = btrfs_resume_balance_async(fs_info); | ||
1191 | if (ret) | ||
1192 | goto restore; | ||
1193 | |||
1190 | sb->s_flags &= ~MS_RDONLY; | 1194 | sb->s_flags &= ~MS_RDONLY; |
1191 | } | 1195 | } |
1192 | 1196 | ||
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 2017d0ff511c..8abeae4224f9 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -690,6 +690,8 @@ static noinline int drop_one_dir_item(struct btrfs_trans_handle *trans, | |||
690 | kfree(name); | 690 | kfree(name); |
691 | 691 | ||
692 | iput(inode); | 692 | iput(inode); |
693 | |||
694 | btrfs_run_delayed_items(trans, root); | ||
693 | return ret; | 695 | return ret; |
694 | } | 696 | } |
695 | 697 | ||
@@ -895,6 +897,7 @@ again: | |||
895 | ret = btrfs_unlink_inode(trans, root, dir, | 897 | ret = btrfs_unlink_inode(trans, root, dir, |
896 | inode, victim_name, | 898 | inode, victim_name, |
897 | victim_name_len); | 899 | victim_name_len); |
900 | btrfs_run_delayed_items(trans, root); | ||
898 | } | 901 | } |
899 | kfree(victim_name); | 902 | kfree(victim_name); |
900 | ptr = (unsigned long)(victim_ref + 1) + victim_name_len; | 903 | ptr = (unsigned long)(victim_ref + 1) + victim_name_len; |
@@ -1475,6 +1478,9 @@ again: | |||
1475 | ret = btrfs_unlink_inode(trans, root, dir, inode, | 1478 | ret = btrfs_unlink_inode(trans, root, dir, inode, |
1476 | name, name_len); | 1479 | name, name_len); |
1477 | BUG_ON(ret); | 1480 | BUG_ON(ret); |
1481 | |||
1482 | btrfs_run_delayed_items(trans, root); | ||
1483 | |||
1478 | kfree(name); | 1484 | kfree(name); |
1479 | iput(inode); | 1485 | iput(inode); |
1480 | 1486 | ||
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 8a3d2594b807..ecaad40e7ef4 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -2845,31 +2845,48 @@ out: | |||
2845 | 2845 | ||
2846 | static int balance_kthread(void *data) | 2846 | static int balance_kthread(void *data) |
2847 | { | 2847 | { |
2848 | struct btrfs_balance_control *bctl = | 2848 | struct btrfs_fs_info *fs_info = data; |
2849 | (struct btrfs_balance_control *)data; | ||
2850 | struct btrfs_fs_info *fs_info = bctl->fs_info; | ||
2851 | int ret = 0; | 2849 | int ret = 0; |
2852 | 2850 | ||
2853 | mutex_lock(&fs_info->volume_mutex); | 2851 | mutex_lock(&fs_info->volume_mutex); |
2854 | mutex_lock(&fs_info->balance_mutex); | 2852 | mutex_lock(&fs_info->balance_mutex); |
2855 | 2853 | ||
2856 | set_balance_control(bctl); | 2854 | if (fs_info->balance_ctl) { |
2857 | |||
2858 | if (btrfs_test_opt(fs_info->tree_root, SKIP_BALANCE)) { | ||
2859 | printk(KERN_INFO "btrfs: force skipping balance\n"); | ||
2860 | } else { | ||
2861 | printk(KERN_INFO "btrfs: continuing balance\n"); | 2855 | printk(KERN_INFO "btrfs: continuing balance\n"); |
2862 | ret = btrfs_balance(bctl, NULL); | 2856 | ret = btrfs_balance(fs_info->balance_ctl, NULL); |
2863 | } | 2857 | } |
2864 | 2858 | ||
2865 | mutex_unlock(&fs_info->balance_mutex); | 2859 | mutex_unlock(&fs_info->balance_mutex); |
2866 | mutex_unlock(&fs_info->volume_mutex); | 2860 | mutex_unlock(&fs_info->volume_mutex); |
2861 | |||
2867 | return ret; | 2862 | return ret; |
2868 | } | 2863 | } |
2869 | 2864 | ||
2870 | int btrfs_recover_balance(struct btrfs_root *tree_root) | 2865 | int btrfs_resume_balance_async(struct btrfs_fs_info *fs_info) |
2871 | { | 2866 | { |
2872 | struct task_struct *tsk; | 2867 | struct task_struct *tsk; |
2868 | |||
2869 | spin_lock(&fs_info->balance_lock); | ||
2870 | if (!fs_info->balance_ctl) { | ||
2871 | spin_unlock(&fs_info->balance_lock); | ||
2872 | return 0; | ||
2873 | } | ||
2874 | spin_unlock(&fs_info->balance_lock); | ||
2875 | |||
2876 | if (btrfs_test_opt(fs_info->tree_root, SKIP_BALANCE)) { | ||
2877 | printk(KERN_INFO "btrfs: force skipping balance\n"); | ||
2878 | return 0; | ||
2879 | } | ||
2880 | |||
2881 | tsk = kthread_run(balance_kthread, fs_info, "btrfs-balance"); | ||
2882 | if (IS_ERR(tsk)) | ||
2883 | return PTR_ERR(tsk); | ||
2884 | |||
2885 | return 0; | ||
2886 | } | ||
2887 | |||
2888 | int btrfs_recover_balance(struct btrfs_fs_info *fs_info) | ||
2889 | { | ||
2873 | struct btrfs_balance_control *bctl; | 2890 | struct btrfs_balance_control *bctl; |
2874 | struct btrfs_balance_item *item; | 2891 | struct btrfs_balance_item *item; |
2875 | struct btrfs_disk_balance_args disk_bargs; | 2892 | struct btrfs_disk_balance_args disk_bargs; |
@@ -2882,29 +2899,30 @@ int btrfs_recover_balance(struct btrfs_root *tree_root) | |||
2882 | if (!path) | 2899 | if (!path) |
2883 | return -ENOMEM; | 2900 | return -ENOMEM; |
2884 | 2901 | ||
2885 | bctl = kzalloc(sizeof(*bctl), GFP_NOFS); | ||
2886 | if (!bctl) { | ||
2887 | ret = -ENOMEM; | ||
2888 | goto out; | ||
2889 | } | ||
2890 | |||
2891 | key.objectid = BTRFS_BALANCE_OBJECTID; | 2902 | key.objectid = BTRFS_BALANCE_OBJECTID; |
2892 | key.type = BTRFS_BALANCE_ITEM_KEY; | 2903 | key.type = BTRFS_BALANCE_ITEM_KEY; |
2893 | key.offset = 0; | 2904 | key.offset = 0; |
2894 | 2905 | ||
2895 | ret = btrfs_search_slot(NULL, tree_root, &key, path, 0, 0); | 2906 | ret = btrfs_search_slot(NULL, fs_info->tree_root, &key, path, 0, 0); |
2896 | if (ret < 0) | 2907 | if (ret < 0) |
2897 | goto out_bctl; | 2908 | goto out; |
2898 | if (ret > 0) { /* ret = -ENOENT; */ | 2909 | if (ret > 0) { /* ret = -ENOENT; */ |
2899 | ret = 0; | 2910 | ret = 0; |
2900 | goto out_bctl; | 2911 | goto out; |
2912 | } | ||
2913 | |||
2914 | bctl = kzalloc(sizeof(*bctl), GFP_NOFS); | ||
2915 | if (!bctl) { | ||
2916 | ret = -ENOMEM; | ||
2917 | goto out; | ||
2901 | } | 2918 | } |
2902 | 2919 | ||
2903 | leaf = path->nodes[0]; | 2920 | leaf = path->nodes[0]; |
2904 | item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_balance_item); | 2921 | item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_balance_item); |
2905 | 2922 | ||
2906 | bctl->fs_info = tree_root->fs_info; | 2923 | bctl->fs_info = fs_info; |
2907 | bctl->flags = btrfs_balance_flags(leaf, item) | BTRFS_BALANCE_RESUME; | 2924 | bctl->flags = btrfs_balance_flags(leaf, item); |
2925 | bctl->flags |= BTRFS_BALANCE_RESUME; | ||
2908 | 2926 | ||
2909 | btrfs_balance_data(leaf, item, &disk_bargs); | 2927 | btrfs_balance_data(leaf, item, &disk_bargs); |
2910 | btrfs_disk_balance_args_to_cpu(&bctl->data, &disk_bargs); | 2928 | btrfs_disk_balance_args_to_cpu(&bctl->data, &disk_bargs); |
@@ -2913,14 +2931,13 @@ int btrfs_recover_balance(struct btrfs_root *tree_root) | |||
2913 | btrfs_balance_sys(leaf, item, &disk_bargs); | 2931 | btrfs_balance_sys(leaf, item, &disk_bargs); |
2914 | btrfs_disk_balance_args_to_cpu(&bctl->sys, &disk_bargs); | 2932 | btrfs_disk_balance_args_to_cpu(&bctl->sys, &disk_bargs); |
2915 | 2933 | ||
2916 | tsk = kthread_run(balance_kthread, bctl, "btrfs-balance"); | 2934 | mutex_lock(&fs_info->volume_mutex); |
2917 | if (IS_ERR(tsk)) | 2935 | mutex_lock(&fs_info->balance_mutex); |
2918 | ret = PTR_ERR(tsk); | ||
2919 | else | ||
2920 | goto out; | ||
2921 | 2936 | ||
2922 | out_bctl: | 2937 | set_balance_control(bctl); |
2923 | kfree(bctl); | 2938 | |
2939 | mutex_unlock(&fs_info->balance_mutex); | ||
2940 | mutex_unlock(&fs_info->volume_mutex); | ||
2924 | out: | 2941 | out: |
2925 | btrfs_free_path(path); | 2942 | btrfs_free_path(path); |
2926 | return ret; | 2943 | return ret; |
@@ -4061,16 +4078,18 @@ static void btrfs_end_bio(struct bio *bio, int err) | |||
4061 | 4078 | ||
4062 | BUG_ON(stripe_index >= bbio->num_stripes); | 4079 | BUG_ON(stripe_index >= bbio->num_stripes); |
4063 | dev = bbio->stripes[stripe_index].dev; | 4080 | dev = bbio->stripes[stripe_index].dev; |
4064 | if (bio->bi_rw & WRITE) | 4081 | if (dev->bdev) { |
4065 | btrfs_dev_stat_inc(dev, | 4082 | if (bio->bi_rw & WRITE) |
4066 | BTRFS_DEV_STAT_WRITE_ERRS); | 4083 | btrfs_dev_stat_inc(dev, |
4067 | else | 4084 | BTRFS_DEV_STAT_WRITE_ERRS); |
4068 | btrfs_dev_stat_inc(dev, | 4085 | else |
4069 | BTRFS_DEV_STAT_READ_ERRS); | 4086 | btrfs_dev_stat_inc(dev, |
4070 | if ((bio->bi_rw & WRITE_FLUSH) == WRITE_FLUSH) | 4087 | BTRFS_DEV_STAT_READ_ERRS); |
4071 | btrfs_dev_stat_inc(dev, | 4088 | if ((bio->bi_rw & WRITE_FLUSH) == WRITE_FLUSH) |
4072 | BTRFS_DEV_STAT_FLUSH_ERRS); | 4089 | btrfs_dev_stat_inc(dev, |
4073 | btrfs_dev_stat_print_on_error(dev); | 4090 | BTRFS_DEV_STAT_FLUSH_ERRS); |
4091 | btrfs_dev_stat_print_on_error(dev); | ||
4092 | } | ||
4074 | } | 4093 | } |
4075 | } | 4094 | } |
4076 | 4095 | ||
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index 74366f27a76b..95f6637614db 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h | |||
@@ -281,7 +281,8 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size); | |||
281 | int btrfs_init_new_device(struct btrfs_root *root, char *path); | 281 | int btrfs_init_new_device(struct btrfs_root *root, char *path); |
282 | int btrfs_balance(struct btrfs_balance_control *bctl, | 282 | int btrfs_balance(struct btrfs_balance_control *bctl, |
283 | struct btrfs_ioctl_balance_args *bargs); | 283 | struct btrfs_ioctl_balance_args *bargs); |
284 | int btrfs_recover_balance(struct btrfs_root *tree_root); | 284 | int btrfs_resume_balance_async(struct btrfs_fs_info *fs_info); |
285 | int btrfs_recover_balance(struct btrfs_fs_info *fs_info); | ||
285 | int btrfs_pause_balance(struct btrfs_fs_info *fs_info); | 286 | int btrfs_pause_balance(struct btrfs_fs_info *fs_info); |
286 | int btrfs_cancel_balance(struct btrfs_fs_info *fs_info); | 287 | int btrfs_cancel_balance(struct btrfs_fs_info *fs_info); |
287 | int btrfs_chunk_readonly(struct btrfs_root *root, u64 chunk_offset); | 288 | int btrfs_chunk_readonly(struct btrfs_root *root, u64 chunk_offset); |
diff --git a/fs/buffer.c b/fs/buffer.c index 838a9cf246bd..c7062c896d7c 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -1036,6 +1036,9 @@ grow_buffers(struct block_device *bdev, sector_t block, int size) | |||
1036 | static struct buffer_head * | 1036 | static struct buffer_head * |
1037 | __getblk_slow(struct block_device *bdev, sector_t block, int size) | 1037 | __getblk_slow(struct block_device *bdev, sector_t block, int size) |
1038 | { | 1038 | { |
1039 | int ret; | ||
1040 | struct buffer_head *bh; | ||
1041 | |||
1039 | /* Size must be multiple of hard sectorsize */ | 1042 | /* Size must be multiple of hard sectorsize */ |
1040 | if (unlikely(size & (bdev_logical_block_size(bdev)-1) || | 1043 | if (unlikely(size & (bdev_logical_block_size(bdev)-1) || |
1041 | (size < 512 || size > PAGE_SIZE))) { | 1044 | (size < 512 || size > PAGE_SIZE))) { |
@@ -1048,20 +1051,21 @@ __getblk_slow(struct block_device *bdev, sector_t block, int size) | |||
1048 | return NULL; | 1051 | return NULL; |
1049 | } | 1052 | } |
1050 | 1053 | ||
1051 | for (;;) { | 1054 | retry: |
1052 | struct buffer_head * bh; | 1055 | bh = __find_get_block(bdev, block, size); |
1053 | int ret; | 1056 | if (bh) |
1057 | return bh; | ||
1054 | 1058 | ||
1059 | ret = grow_buffers(bdev, block, size); | ||
1060 | if (ret == 0) { | ||
1061 | free_more_memory(); | ||
1062 | goto retry; | ||
1063 | } else if (ret > 0) { | ||
1055 | bh = __find_get_block(bdev, block, size); | 1064 | bh = __find_get_block(bdev, block, size); |
1056 | if (bh) | 1065 | if (bh) |
1057 | return bh; | 1066 | return bh; |
1058 | |||
1059 | ret = grow_buffers(bdev, block, size); | ||
1060 | if (ret < 0) | ||
1061 | return NULL; | ||
1062 | if (ret == 0) | ||
1063 | free_more_memory(); | ||
1064 | } | 1067 | } |
1068 | return NULL; | ||
1065 | } | 1069 | } |
1066 | 1070 | ||
1067 | /* | 1071 | /* |
diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index 7f0771d3894e..b0b5f7cdfffa 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c | |||
@@ -567,7 +567,7 @@ lookup_again: | |||
567 | if (ret < 0) | 567 | if (ret < 0) |
568 | goto create_error; | 568 | goto create_error; |
569 | start = jiffies; | 569 | start = jiffies; |
570 | ret = vfs_create(dir->d_inode, next, S_IFREG, NULL); | 570 | ret = vfs_create(dir->d_inode, next, S_IFREG, true); |
571 | cachefiles_hist(cachefiles_create_histogram, start); | 571 | cachefiles_hist(cachefiles_create_histogram, start); |
572 | if (ret < 0) | 572 | if (ret < 0) |
573 | goto create_error; | 573 | goto create_error; |
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 3e8094be4604..00894ff9246c 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -576,7 +576,7 @@ static int is_root_ceph_dentry(struct inode *inode, struct dentry *dentry) | |||
576 | * the MDS so that it gets our 'caps wanted' value in a single op. | 576 | * the MDS so that it gets our 'caps wanted' value in a single op. |
577 | */ | 577 | */ |
578 | static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry, | 578 | static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry, |
579 | struct nameidata *nd) | 579 | unsigned int flags) |
580 | { | 580 | { |
581 | struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb); | 581 | struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb); |
582 | struct ceph_mds_client *mdsc = fsc->mdsc; | 582 | struct ceph_mds_client *mdsc = fsc->mdsc; |
@@ -594,14 +594,6 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry, | |||
594 | if (err < 0) | 594 | if (err < 0) |
595 | return ERR_PTR(err); | 595 | return ERR_PTR(err); |
596 | 596 | ||
597 | /* open (but not create!) intent? */ | ||
598 | if (nd && | ||
599 | (nd->flags & LOOKUP_OPEN) && | ||
600 | !(nd->intent.open.flags & O_CREAT)) { | ||
601 | int mode = nd->intent.open.create_mode & ~current->fs->umask; | ||
602 | return ceph_lookup_open(dir, dentry, nd, mode, 1); | ||
603 | } | ||
604 | |||
605 | /* can we conclude ENOENT locally? */ | 597 | /* can we conclude ENOENT locally? */ |
606 | if (dentry->d_inode == NULL) { | 598 | if (dentry->d_inode == NULL) { |
607 | struct ceph_inode_info *ci = ceph_inode(dir); | 599 | struct ceph_inode_info *ci = ceph_inode(dir); |
@@ -642,13 +634,51 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry, | |||
642 | return dentry; | 634 | return dentry; |
643 | } | 635 | } |
644 | 636 | ||
637 | int ceph_atomic_open(struct inode *dir, struct dentry *dentry, | ||
638 | struct file *file, unsigned flags, umode_t mode, | ||
639 | int *opened) | ||
640 | { | ||
641 | int err; | ||
642 | struct dentry *res = NULL; | ||
643 | |||
644 | if (!(flags & O_CREAT)) { | ||
645 | if (dentry->d_name.len > NAME_MAX) | ||
646 | return -ENAMETOOLONG; | ||
647 | |||
648 | err = ceph_init_dentry(dentry); | ||
649 | if (err < 0) | ||
650 | return err; | ||
651 | |||
652 | return ceph_lookup_open(dir, dentry, file, flags, mode, opened); | ||
653 | } | ||
654 | |||
655 | if (d_unhashed(dentry)) { | ||
656 | res = ceph_lookup(dir, dentry, 0); | ||
657 | if (IS_ERR(res)) | ||
658 | return PTR_ERR(res); | ||
659 | |||
660 | if (res) | ||
661 | dentry = res; | ||
662 | } | ||
663 | |||
664 | /* We don't deal with positive dentries here */ | ||
665 | if (dentry->d_inode) | ||
666 | return finish_no_open(file, res); | ||
667 | |||
668 | *opened |= FILE_CREATED; | ||
669 | err = ceph_lookup_open(dir, dentry, file, flags, mode, opened); | ||
670 | dput(res); | ||
671 | |||
672 | return err; | ||
673 | } | ||
674 | |||
645 | /* | 675 | /* |
646 | * If we do a create but get no trace back from the MDS, follow up with | 676 | * If we do a create but get no trace back from the MDS, follow up with |
647 | * a lookup (the VFS expects us to link up the provided dentry). | 677 | * a lookup (the VFS expects us to link up the provided dentry). |
648 | */ | 678 | */ |
649 | int ceph_handle_notrace_create(struct inode *dir, struct dentry *dentry) | 679 | int ceph_handle_notrace_create(struct inode *dir, struct dentry *dentry) |
650 | { | 680 | { |
651 | struct dentry *result = ceph_lookup(dir, dentry, NULL); | 681 | struct dentry *result = ceph_lookup(dir, dentry, 0); |
652 | 682 | ||
653 | if (result && !IS_ERR(result)) { | 683 | if (result && !IS_ERR(result)) { |
654 | /* | 684 | /* |
@@ -700,25 +730,9 @@ static int ceph_mknod(struct inode *dir, struct dentry *dentry, | |||
700 | } | 730 | } |
701 | 731 | ||
702 | static int ceph_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 732 | static int ceph_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
703 | struct nameidata *nd) | 733 | bool excl) |
704 | { | 734 | { |
705 | dout("create in dir %p dentry %p name '%.*s'\n", | 735 | return ceph_mknod(dir, dentry, mode, 0); |
706 | dir, dentry, dentry->d_name.len, dentry->d_name.name); | ||
707 | |||
708 | if (ceph_snap(dir) != CEPH_NOSNAP) | ||
709 | return -EROFS; | ||
710 | |||
711 | if (nd) { | ||
712 | BUG_ON((nd->flags & LOOKUP_OPEN) == 0); | ||
713 | dentry = ceph_lookup_open(dir, dentry, nd, mode, 0); | ||
714 | /* hrm, what should i do here if we get aliased? */ | ||
715 | if (IS_ERR(dentry)) | ||
716 | return PTR_ERR(dentry); | ||
717 | return 0; | ||
718 | } | ||
719 | |||
720 | /* fall back to mknod */ | ||
721 | return ceph_mknod(dir, dentry, (mode & ~S_IFMT) | S_IFREG, 0); | ||
722 | } | 736 | } |
723 | 737 | ||
724 | static int ceph_symlink(struct inode *dir, struct dentry *dentry, | 738 | static int ceph_symlink(struct inode *dir, struct dentry *dentry, |
@@ -1028,12 +1042,12 @@ static int dir_lease_is_valid(struct inode *dir, struct dentry *dentry) | |||
1028 | /* | 1042 | /* |
1029 | * Check if cached dentry can be trusted. | 1043 | * Check if cached dentry can be trusted. |
1030 | */ | 1044 | */ |
1031 | static int ceph_d_revalidate(struct dentry *dentry, struct nameidata *nd) | 1045 | static int ceph_d_revalidate(struct dentry *dentry, unsigned int flags) |
1032 | { | 1046 | { |
1033 | int valid = 0; | 1047 | int valid = 0; |
1034 | struct inode *dir; | 1048 | struct inode *dir; |
1035 | 1049 | ||
1036 | if (nd && nd->flags & LOOKUP_RCU) | 1050 | if (flags & LOOKUP_RCU) |
1037 | return -ECHILD; | 1051 | return -ECHILD; |
1038 | 1052 | ||
1039 | dout("d_revalidate %p '%.*s' inode %p offset %lld\n", dentry, | 1053 | dout("d_revalidate %p '%.*s' inode %p offset %lld\n", dentry, |
@@ -1080,7 +1094,7 @@ static void ceph_d_release(struct dentry *dentry) | |||
1080 | } | 1094 | } |
1081 | 1095 | ||
1082 | static int ceph_snapdir_d_revalidate(struct dentry *dentry, | 1096 | static int ceph_snapdir_d_revalidate(struct dentry *dentry, |
1083 | struct nameidata *nd) | 1097 | unsigned int flags) |
1084 | { | 1098 | { |
1085 | /* | 1099 | /* |
1086 | * Eventually, we'll want to revalidate snapped metadata | 1100 | * Eventually, we'll want to revalidate snapped metadata |
@@ -1357,6 +1371,7 @@ const struct inode_operations ceph_dir_iops = { | |||
1357 | .rmdir = ceph_unlink, | 1371 | .rmdir = ceph_unlink, |
1358 | .rename = ceph_rename, | 1372 | .rename = ceph_rename, |
1359 | .create = ceph_create, | 1373 | .create = ceph_create, |
1374 | .atomic_open = ceph_atomic_open, | ||
1360 | }; | 1375 | }; |
1361 | 1376 | ||
1362 | const struct dentry_operations ceph_dentry_ops = { | 1377 | const struct dentry_operations ceph_dentry_ops = { |
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 988d4f302e48..1b81d6c31878 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
@@ -213,22 +213,15 @@ out: | |||
213 | * may_open() fails, the struct *file gets cleaned up (i.e. | 213 | * may_open() fails, the struct *file gets cleaned up (i.e. |
214 | * ceph_release gets called). So fear not! | 214 | * ceph_release gets called). So fear not! |
215 | */ | 215 | */ |
216 | /* | 216 | int ceph_lookup_open(struct inode *dir, struct dentry *dentry, |
217 | * flags | 217 | struct file *file, unsigned flags, umode_t mode, |
218 | * path_lookup_open -> LOOKUP_OPEN | 218 | int *opened) |
219 | * path_lookup_create -> LOOKUP_OPEN|LOOKUP_CREATE | ||
220 | */ | ||
221 | struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry, | ||
222 | struct nameidata *nd, int mode, | ||
223 | int locked_dir) | ||
224 | { | 219 | { |
225 | struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb); | 220 | struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb); |
226 | struct ceph_mds_client *mdsc = fsc->mdsc; | 221 | struct ceph_mds_client *mdsc = fsc->mdsc; |
227 | struct file *file; | ||
228 | struct ceph_mds_request *req; | 222 | struct ceph_mds_request *req; |
229 | struct dentry *ret; | 223 | struct dentry *ret; |
230 | int err; | 224 | int err; |
231 | int flags = nd->intent.open.flags; | ||
232 | 225 | ||
233 | dout("ceph_lookup_open dentry %p '%.*s' flags %d mode 0%o\n", | 226 | dout("ceph_lookup_open dentry %p '%.*s' flags %d mode 0%o\n", |
234 | dentry, dentry->d_name.len, dentry->d_name.name, flags, mode); | 227 | dentry, dentry->d_name.len, dentry->d_name.name, flags, mode); |
@@ -236,7 +229,7 @@ struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry, | |||
236 | /* do the open */ | 229 | /* do the open */ |
237 | req = prepare_open_request(dir->i_sb, flags, mode); | 230 | req = prepare_open_request(dir->i_sb, flags, mode); |
238 | if (IS_ERR(req)) | 231 | if (IS_ERR(req)) |
239 | return ERR_CAST(req); | 232 | return PTR_ERR(req); |
240 | req->r_dentry = dget(dentry); | 233 | req->r_dentry = dget(dentry); |
241 | req->r_num_caps = 2; | 234 | req->r_num_caps = 2; |
242 | if (flags & O_CREAT) { | 235 | if (flags & O_CREAT) { |
@@ -254,14 +247,17 @@ struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry, | |||
254 | err = ceph_handle_notrace_create(dir, dentry); | 247 | err = ceph_handle_notrace_create(dir, dentry); |
255 | if (err) | 248 | if (err) |
256 | goto out; | 249 | goto out; |
257 | file = lookup_instantiate_filp(nd, req->r_dentry, ceph_open); | 250 | err = finish_open(file, req->r_dentry, ceph_open, opened); |
258 | if (IS_ERR(file)) | ||
259 | err = PTR_ERR(file); | ||
260 | out: | 251 | out: |
261 | ret = ceph_finish_lookup(req, dentry, err); | 252 | ret = ceph_finish_lookup(req, dentry, err); |
262 | ceph_mdsc_put_request(req); | 253 | ceph_mdsc_put_request(req); |
263 | dout("ceph_lookup_open result=%p\n", ret); | 254 | dout("ceph_lookup_open result=%p\n", ret); |
264 | return ret; | 255 | |
256 | if (IS_ERR(ret)) | ||
257 | return PTR_ERR(ret); | ||
258 | |||
259 | dput(ret); | ||
260 | return err; | ||
265 | } | 261 | } |
266 | 262 | ||
267 | int ceph_release(struct inode *inode, struct file *file) | 263 | int ceph_release(struct inode *inode, struct file *file) |
diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 1e67dd7305a4..7076109f014d 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c | |||
@@ -871,7 +871,7 @@ static struct dentry *ceph_mount(struct file_system_type *fs_type, | |||
871 | 871 | ||
872 | if (ceph_test_opt(fsc->client, NOSHARE)) | 872 | if (ceph_test_opt(fsc->client, NOSHARE)) |
873 | compare_super = NULL; | 873 | compare_super = NULL; |
874 | sb = sget(fs_type, compare_super, ceph_set_super, fsc); | 874 | sb = sget(fs_type, compare_super, ceph_set_super, flags, fsc); |
875 | if (IS_ERR(sb)) { | 875 | if (IS_ERR(sb)) { |
876 | res = ERR_CAST(sb); | 876 | res = ERR_CAST(sb); |
877 | goto out; | 877 | goto out; |
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index fc35036d258d..f4d5522cb619 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
@@ -806,9 +806,9 @@ extern int ceph_copy_from_page_vector(struct page **pages, | |||
806 | loff_t off, size_t len); | 806 | loff_t off, size_t len); |
807 | extern struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags); | 807 | extern struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags); |
808 | extern int ceph_open(struct inode *inode, struct file *file); | 808 | extern int ceph_open(struct inode *inode, struct file *file); |
809 | extern struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry, | 809 | extern int ceph_lookup_open(struct inode *dir, struct dentry *dentry, |
810 | struct nameidata *nd, int mode, | 810 | struct file *od, unsigned flags, |
811 | int locked_dir); | 811 | umode_t mode, int *opened); |
812 | extern int ceph_release(struct inode *inode, struct file *filp); | 812 | extern int ceph_release(struct inode *inode, struct file *filp); |
813 | 813 | ||
814 | /* dir.c */ | 814 | /* dir.c */ |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 8b6e344eb0ba..a7610cfedf0a 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -257,7 +257,6 @@ cifs_alloc_inode(struct super_block *sb) | |||
257 | static void cifs_i_callback(struct rcu_head *head) | 257 | static void cifs_i_callback(struct rcu_head *head) |
258 | { | 258 | { |
259 | struct inode *inode = container_of(head, struct inode, i_rcu); | 259 | struct inode *inode = container_of(head, struct inode, i_rcu); |
260 | INIT_LIST_HEAD(&inode->i_dentry); | ||
261 | kmem_cache_free(cifs_inode_cachep, CIFS_I(inode)); | 260 | kmem_cache_free(cifs_inode_cachep, CIFS_I(inode)); |
262 | } | 261 | } |
263 | 262 | ||
@@ -638,7 +637,10 @@ cifs_do_mount(struct file_system_type *fs_type, | |||
638 | mnt_data.cifs_sb = cifs_sb; | 637 | mnt_data.cifs_sb = cifs_sb; |
639 | mnt_data.flags = flags; | 638 | mnt_data.flags = flags; |
640 | 639 | ||
641 | sb = sget(fs_type, cifs_match_super, cifs_set_super, &mnt_data); | 640 | /* BB should we make this contingent on mount parm? */ |
641 | flags |= MS_NODIRATIME | MS_NOATIME; | ||
642 | |||
643 | sb = sget(fs_type, cifs_match_super, cifs_set_super, flags, &mnt_data); | ||
642 | if (IS_ERR(sb)) { | 644 | if (IS_ERR(sb)) { |
643 | root = ERR_CAST(sb); | 645 | root = ERR_CAST(sb); |
644 | cifs_umount(cifs_sb); | 646 | cifs_umount(cifs_sb); |
@@ -649,10 +651,6 @@ cifs_do_mount(struct file_system_type *fs_type, | |||
649 | cFYI(1, "Use existing superblock"); | 651 | cFYI(1, "Use existing superblock"); |
650 | cifs_umount(cifs_sb); | 652 | cifs_umount(cifs_sb); |
651 | } else { | 653 | } else { |
652 | sb->s_flags = flags; | ||
653 | /* BB should we make this contingent on mount parm? */ | ||
654 | sb->s_flags |= MS_NODIRATIME | MS_NOATIME; | ||
655 | |||
656 | rc = cifs_read_super(sb); | 654 | rc = cifs_read_super(sb); |
657 | if (rc) { | 655 | if (rc) { |
658 | root = ERR_PTR(rc); | 656 | root = ERR_PTR(rc); |
@@ -778,6 +776,7 @@ struct file_system_type cifs_fs_type = { | |||
778 | }; | 776 | }; |
779 | const struct inode_operations cifs_dir_inode_ops = { | 777 | const struct inode_operations cifs_dir_inode_ops = { |
780 | .create = cifs_create, | 778 | .create = cifs_create, |
779 | .atomic_open = cifs_atomic_open, | ||
781 | .lookup = cifs_lookup, | 780 | .lookup = cifs_lookup, |
782 | .getattr = cifs_getattr, | 781 | .getattr = cifs_getattr, |
783 | .unlink = cifs_unlink, | 782 | .unlink = cifs_unlink, |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 65365358c976..1c49c5a9b27a 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
@@ -45,9 +45,12 @@ extern const struct address_space_operations cifs_addr_ops_smallbuf; | |||
45 | extern const struct inode_operations cifs_dir_inode_ops; | 45 | extern const struct inode_operations cifs_dir_inode_ops; |
46 | extern struct inode *cifs_root_iget(struct super_block *); | 46 | extern struct inode *cifs_root_iget(struct super_block *); |
47 | extern int cifs_create(struct inode *, struct dentry *, umode_t, | 47 | extern int cifs_create(struct inode *, struct dentry *, umode_t, |
48 | struct nameidata *); | 48 | bool excl); |
49 | extern int cifs_atomic_open(struct inode *, struct dentry *, | ||
50 | struct file *, unsigned, umode_t, | ||
51 | int *); | ||
49 | extern struct dentry *cifs_lookup(struct inode *, struct dentry *, | 52 | extern struct dentry *cifs_lookup(struct inode *, struct dentry *, |
50 | struct nameidata *); | 53 | unsigned int); |
51 | extern int cifs_unlink(struct inode *dir, struct dentry *dentry); | 54 | extern int cifs_unlink(struct inode *dir, struct dentry *dentry); |
52 | extern int cifs_hardlink(struct dentry *, struct inode *, struct dentry *); | 55 | extern int cifs_hardlink(struct dentry *, struct inode *, struct dentry *); |
53 | extern int cifs_mknod(struct inode *, struct dentry *, umode_t, dev_t); | 56 | extern int cifs_mknod(struct inode *, struct dentry *, umode_t, dev_t); |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 78db68a5cf44..0ae86ddf2213 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -1653,24 +1653,26 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, | |||
1653 | * If yes, we have encountered a double deliminator | 1653 | * If yes, we have encountered a double deliminator |
1654 | * reset the NULL character to the deliminator | 1654 | * reset the NULL character to the deliminator |
1655 | */ | 1655 | */ |
1656 | if (tmp_end < end && tmp_end[1] == delim) | 1656 | if (tmp_end < end && tmp_end[1] == delim) { |
1657 | tmp_end[0] = delim; | 1657 | tmp_end[0] = delim; |
1658 | 1658 | ||
1659 | /* Keep iterating until we get to a single deliminator | 1659 | /* Keep iterating until we get to a single |
1660 | * OR the end | 1660 | * deliminator OR the end |
1661 | */ | 1661 | */ |
1662 | while ((tmp_end = strchr(tmp_end, delim)) != NULL && | 1662 | while ((tmp_end = strchr(tmp_end, delim)) |
1663 | (tmp_end[1] == delim)) { | 1663 | != NULL && (tmp_end[1] == delim)) { |
1664 | tmp_end = (char *) &tmp_end[2]; | 1664 | tmp_end = (char *) &tmp_end[2]; |
1665 | } | 1665 | } |
1666 | 1666 | ||
1667 | /* Reset var options to point to next element */ | 1667 | /* Reset var options to point to next element */ |
1668 | if (tmp_end) { | 1668 | if (tmp_end) { |
1669 | tmp_end[0] = '\0'; | 1669 | tmp_end[0] = '\0'; |
1670 | options = (char *) &tmp_end[1]; | 1670 | options = (char *) &tmp_end[1]; |
1671 | } else | 1671 | } else |
1672 | /* Reached the end of the mount option string */ | 1672 | /* Reached the end of the mount option |
1673 | options = end; | 1673 | * string */ |
1674 | options = end; | ||
1675 | } | ||
1674 | 1676 | ||
1675 | /* Now build new password string */ | 1677 | /* Now build new password string */ |
1676 | temp_len = strlen(value); | 1678 | temp_len = strlen(value); |
@@ -3493,18 +3495,15 @@ cifs_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) | |||
3493 | * MS-CIFS indicates that servers are only limited by the client's | 3495 | * MS-CIFS indicates that servers are only limited by the client's |
3494 | * bufsize for reads, testing against win98se shows that it throws | 3496 | * bufsize for reads, testing against win98se shows that it throws |
3495 | * INVALID_PARAMETER errors if you try to request too large a read. | 3497 | * INVALID_PARAMETER errors if you try to request too large a read. |
3498 | * OS/2 just sends back short reads. | ||
3496 | * | 3499 | * |
3497 | * If the server advertises a MaxBufferSize of less than one page, | 3500 | * If the server doesn't advertise CAP_LARGE_READ_X, then assume that |
3498 | * assume that it also can't satisfy reads larger than that either. | 3501 | * it can't handle a read request larger than its MaxBufferSize either. |
3499 | * | ||
3500 | * FIXME: Is there a better heuristic for this? | ||
3501 | */ | 3502 | */ |
3502 | if (tcon->unix_ext && (unix_cap & CIFS_UNIX_LARGE_READ_CAP)) | 3503 | if (tcon->unix_ext && (unix_cap & CIFS_UNIX_LARGE_READ_CAP)) |
3503 | defsize = CIFS_DEFAULT_IOSIZE; | 3504 | defsize = CIFS_DEFAULT_IOSIZE; |
3504 | else if (server->capabilities & CAP_LARGE_READ_X) | 3505 | else if (server->capabilities & CAP_LARGE_READ_X) |
3505 | defsize = CIFS_DEFAULT_NON_POSIX_RSIZE; | 3506 | defsize = CIFS_DEFAULT_NON_POSIX_RSIZE; |
3506 | else if (server->maxBuf >= PAGE_CACHE_SIZE) | ||
3507 | defsize = CIFSMaxBufSize; | ||
3508 | else | 3507 | else |
3509 | defsize = server->maxBuf - sizeof(READ_RSP); | 3508 | defsize = server->maxBuf - sizeof(READ_RSP); |
3510 | 3509 | ||
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index ec4e9a2a12f8..a180265a10b5 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -133,108 +133,141 @@ cifs_bp_rename_retry: | |||
133 | return full_path; | 133 | return full_path; |
134 | } | 134 | } |
135 | 135 | ||
136 | /* | ||
137 | * Don't allow the separator character in a path component. | ||
138 | * The VFS will not allow "/", but "\" is allowed by posix. | ||
139 | */ | ||
140 | static int | ||
141 | check_name(struct dentry *direntry) | ||
142 | { | ||
143 | struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb); | ||
144 | int i; | ||
145 | |||
146 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) { | ||
147 | for (i = 0; i < direntry->d_name.len; i++) { | ||
148 | if (direntry->d_name.name[i] == '\\') { | ||
149 | cFYI(1, "Invalid file name"); | ||
150 | return -EINVAL; | ||
151 | } | ||
152 | } | ||
153 | } | ||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | |||
136 | /* Inode operations in similar order to how they appear in Linux file fs.h */ | 158 | /* Inode operations in similar order to how they appear in Linux file fs.h */ |
137 | 159 | ||
138 | int | 160 | static int cifs_do_create(struct inode *inode, struct dentry *direntry, |
139 | cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode, | 161 | int xid, struct tcon_link *tlink, unsigned oflags, |
140 | struct nameidata *nd) | 162 | umode_t mode, __u32 *oplock, __u16 *fileHandle, |
163 | int *created) | ||
141 | { | 164 | { |
142 | int rc = -ENOENT; | 165 | int rc = -ENOENT; |
143 | int xid; | ||
144 | int create_options = CREATE_NOT_DIR; | 166 | int create_options = CREATE_NOT_DIR; |
145 | __u32 oplock = 0; | 167 | int desiredAccess; |
146 | int oflags; | 168 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
147 | /* | 169 | struct cifs_tcon *tcon = tlink_tcon(tlink); |
148 | * BB below access is probably too much for mknod to request | ||
149 | * but we have to do query and setpathinfo so requesting | ||
150 | * less could fail (unless we want to request getatr and setatr | ||
151 | * permissions (only). At least for POSIX we do not have to | ||
152 | * request so much. | ||
153 | */ | ||
154 | int desiredAccess = GENERIC_READ | GENERIC_WRITE; | ||
155 | __u16 fileHandle; | ||
156 | struct cifs_sb_info *cifs_sb; | ||
157 | struct tcon_link *tlink; | ||
158 | struct cifs_tcon *tcon; | ||
159 | char *full_path = NULL; | 170 | char *full_path = NULL; |
160 | FILE_ALL_INFO *buf = NULL; | 171 | FILE_ALL_INFO *buf = NULL; |
161 | struct inode *newinode = NULL; | 172 | struct inode *newinode = NULL; |
162 | int disposition = FILE_OVERWRITE_IF; | 173 | int disposition; |
163 | |||
164 | xid = GetXid(); | ||
165 | |||
166 | cifs_sb = CIFS_SB(inode->i_sb); | ||
167 | tlink = cifs_sb_tlink(cifs_sb); | ||
168 | if (IS_ERR(tlink)) { | ||
169 | FreeXid(xid); | ||
170 | return PTR_ERR(tlink); | ||
171 | } | ||
172 | tcon = tlink_tcon(tlink); | ||
173 | 174 | ||
175 | *oplock = 0; | ||
174 | if (tcon->ses->server->oplocks) | 176 | if (tcon->ses->server->oplocks) |
175 | oplock = REQ_OPLOCK; | 177 | *oplock = REQ_OPLOCK; |
176 | |||
177 | if (nd) | ||
178 | oflags = nd->intent.open.file->f_flags; | ||
179 | else | ||
180 | oflags = O_RDONLY | O_CREAT; | ||
181 | 178 | ||
182 | full_path = build_path_from_dentry(direntry); | 179 | full_path = build_path_from_dentry(direntry); |
183 | if (full_path == NULL) { | 180 | if (full_path == NULL) { |
184 | rc = -ENOMEM; | 181 | rc = -ENOMEM; |
185 | goto cifs_create_out; | 182 | goto out; |
186 | } | 183 | } |
187 | 184 | ||
188 | if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) && | 185 | if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) && |
186 | !tcon->broken_posix_open && | ||
189 | (CIFS_UNIX_POSIX_PATH_OPS_CAP & | 187 | (CIFS_UNIX_POSIX_PATH_OPS_CAP & |
190 | le64_to_cpu(tcon->fsUnixInfo.Capability))) { | 188 | le64_to_cpu(tcon->fsUnixInfo.Capability))) { |
191 | rc = cifs_posix_open(full_path, &newinode, | 189 | rc = cifs_posix_open(full_path, &newinode, |
192 | inode->i_sb, mode, oflags, &oplock, &fileHandle, xid); | 190 | inode->i_sb, mode, oflags, oplock, fileHandle, xid); |
193 | /* EIO could indicate that (posix open) operation is not | 191 | switch (rc) { |
194 | supported, despite what server claimed in capability | 192 | case 0: |
195 | negotiation. EREMOTE indicates DFS junction, which is not | 193 | if (newinode == NULL) { |
196 | handled in posix open */ | 194 | /* query inode info */ |
197 | |||
198 | if (rc == 0) { | ||
199 | if (newinode == NULL) /* query inode info */ | ||
200 | goto cifs_create_get_file_info; | 195 | goto cifs_create_get_file_info; |
201 | else /* success, no need to query */ | 196 | } |
202 | goto cifs_create_set_dentry; | 197 | |
203 | } else if ((rc != -EIO) && (rc != -EREMOTE) && | 198 | if (!S_ISREG(newinode->i_mode)) { |
204 | (rc != -EOPNOTSUPP) && (rc != -EINVAL)) | 199 | /* |
205 | goto cifs_create_out; | 200 | * The server may allow us to open things like |
206 | /* else fallthrough to retry, using older open call, this is | 201 | * FIFOs, but the client isn't set up to deal |
207 | case where server does not support this SMB level, and | 202 | * with that. If it's not a regular file, just |
208 | falsely claims capability (also get here for DFS case | 203 | * close it and proceed as if it were a normal |
209 | which should be rare for path not covered on files) */ | 204 | * lookup. |
210 | } | 205 | */ |
206 | CIFSSMBClose(xid, tcon, *fileHandle); | ||
207 | goto cifs_create_get_file_info; | ||
208 | } | ||
209 | /* success, no need to query */ | ||
210 | goto cifs_create_set_dentry; | ||
211 | |||
212 | case -ENOENT: | ||
213 | goto cifs_create_get_file_info; | ||
214 | |||
215 | case -EIO: | ||
216 | case -EINVAL: | ||
217 | /* | ||
218 | * EIO could indicate that (posix open) operation is not | ||
219 | * supported, despite what server claimed in capability | ||
220 | * negotiation. | ||
221 | * | ||
222 | * POSIX open in samba versions 3.3.1 and earlier could | ||
223 | * incorrectly fail with invalid parameter. | ||
224 | */ | ||
225 | tcon->broken_posix_open = true; | ||
226 | break; | ||
227 | |||
228 | case -EREMOTE: | ||
229 | case -EOPNOTSUPP: | ||
230 | /* | ||
231 | * EREMOTE indicates DFS junction, which is not handled | ||
232 | * in posix open. If either that or op not supported | ||
233 | * returned, follow the normal lookup. | ||
234 | */ | ||
235 | break; | ||
211 | 236 | ||
212 | if (nd) { | 237 | default: |
213 | /* if the file is going to stay open, then we | 238 | goto out; |
214 | need to set the desired access properly */ | 239 | } |
215 | desiredAccess = 0; | 240 | /* |
216 | if (OPEN_FMODE(oflags) & FMODE_READ) | 241 | * fallthrough to retry, using older open call, this is case |
217 | desiredAccess |= GENERIC_READ; /* is this too little? */ | 242 | * where server does not support this SMB level, and falsely |
218 | if (OPEN_FMODE(oflags) & FMODE_WRITE) | 243 | * claims capability (also get here for DFS case which should be |
219 | desiredAccess |= GENERIC_WRITE; | 244 | * rare for path not covered on files) |
220 | 245 | */ | |
221 | if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) | ||
222 | disposition = FILE_CREATE; | ||
223 | else if ((oflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC)) | ||
224 | disposition = FILE_OVERWRITE_IF; | ||
225 | else if ((oflags & O_CREAT) == O_CREAT) | ||
226 | disposition = FILE_OPEN_IF; | ||
227 | else | ||
228 | cFYI(1, "Create flag not set in create function"); | ||
229 | } | 246 | } |
230 | 247 | ||
248 | desiredAccess = 0; | ||
249 | if (OPEN_FMODE(oflags) & FMODE_READ) | ||
250 | desiredAccess |= GENERIC_READ; /* is this too little? */ | ||
251 | if (OPEN_FMODE(oflags) & FMODE_WRITE) | ||
252 | desiredAccess |= GENERIC_WRITE; | ||
253 | |||
254 | disposition = FILE_OVERWRITE_IF; | ||
255 | if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) | ||
256 | disposition = FILE_CREATE; | ||
257 | else if ((oflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC)) | ||
258 | disposition = FILE_OVERWRITE_IF; | ||
259 | else if ((oflags & O_CREAT) == O_CREAT) | ||
260 | disposition = FILE_OPEN_IF; | ||
261 | else | ||
262 | cFYI(1, "Create flag not set in create function"); | ||
263 | |||
231 | /* BB add processing to set equivalent of mode - e.g. via CreateX with | 264 | /* BB add processing to set equivalent of mode - e.g. via CreateX with |
232 | ACLs */ | 265 | ACLs */ |
233 | 266 | ||
234 | buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); | 267 | buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); |
235 | if (buf == NULL) { | 268 | if (buf == NULL) { |
236 | rc = -ENOMEM; | 269 | rc = -ENOMEM; |
237 | goto cifs_create_out; | 270 | goto out; |
238 | } | 271 | } |
239 | 272 | ||
240 | /* | 273 | /* |
@@ -250,7 +283,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode, | |||
250 | if (tcon->ses->capabilities & CAP_NT_SMBS) | 283 | if (tcon->ses->capabilities & CAP_NT_SMBS) |
251 | rc = CIFSSMBOpen(xid, tcon, full_path, disposition, | 284 | rc = CIFSSMBOpen(xid, tcon, full_path, disposition, |
252 | desiredAccess, create_options, | 285 | desiredAccess, create_options, |
253 | &fileHandle, &oplock, buf, cifs_sb->local_nls, | 286 | fileHandle, oplock, buf, cifs_sb->local_nls, |
254 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | 287 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
255 | else | 288 | else |
256 | rc = -EIO; /* no NT SMB support fall into legacy open below */ | 289 | rc = -EIO; /* no NT SMB support fall into legacy open below */ |
@@ -259,17 +292,17 @@ cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode, | |||
259 | /* old server, retry the open legacy style */ | 292 | /* old server, retry the open legacy style */ |
260 | rc = SMBLegacyOpen(xid, tcon, full_path, disposition, | 293 | rc = SMBLegacyOpen(xid, tcon, full_path, disposition, |
261 | desiredAccess, create_options, | 294 | desiredAccess, create_options, |
262 | &fileHandle, &oplock, buf, cifs_sb->local_nls, | 295 | fileHandle, oplock, buf, cifs_sb->local_nls, |
263 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | 296 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
264 | } | 297 | } |
265 | if (rc) { | 298 | if (rc) { |
266 | cFYI(1, "cifs_create returned 0x%x", rc); | 299 | cFYI(1, "cifs_create returned 0x%x", rc); |
267 | goto cifs_create_out; | 300 | goto out; |
268 | } | 301 | } |
269 | 302 | ||
270 | /* If Open reported that we actually created a file | 303 | /* If Open reported that we actually created a file |
271 | then we now have to set the mode if possible */ | 304 | then we now have to set the mode if possible */ |
272 | if ((tcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) { | 305 | if ((tcon->unix_ext) && (*oplock & CIFS_CREATE_ACTION)) { |
273 | struct cifs_unix_set_info_args args = { | 306 | struct cifs_unix_set_info_args args = { |
274 | .mode = mode, | 307 | .mode = mode, |
275 | .ctime = NO_CHANGE_64, | 308 | .ctime = NO_CHANGE_64, |
@@ -278,6 +311,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode, | |||
278 | .device = 0, | 311 | .device = 0, |
279 | }; | 312 | }; |
280 | 313 | ||
314 | *created |= FILE_CREATED; | ||
281 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 315 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
282 | args.uid = (__u64) current_fsuid(); | 316 | args.uid = (__u64) current_fsuid(); |
283 | if (inode->i_mode & S_ISGID) | 317 | if (inode->i_mode & S_ISGID) |
@@ -288,7 +322,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode, | |||
288 | args.uid = NO_CHANGE_64; | 322 | args.uid = NO_CHANGE_64; |
289 | args.gid = NO_CHANGE_64; | 323 | args.gid = NO_CHANGE_64; |
290 | } | 324 | } |
291 | CIFSSMBUnixSetFileInfo(xid, tcon, &args, fileHandle, | 325 | CIFSSMBUnixSetFileInfo(xid, tcon, &args, *fileHandle, |
292 | current->tgid); | 326 | current->tgid); |
293 | } else { | 327 | } else { |
294 | /* BB implement mode setting via Windows security | 328 | /* BB implement mode setting via Windows security |
@@ -305,11 +339,11 @@ cifs_create_get_file_info: | |||
305 | inode->i_sb, xid); | 339 | inode->i_sb, xid); |
306 | else { | 340 | else { |
307 | rc = cifs_get_inode_info(&newinode, full_path, buf, | 341 | rc = cifs_get_inode_info(&newinode, full_path, buf, |
308 | inode->i_sb, xid, &fileHandle); | 342 | inode->i_sb, xid, fileHandle); |
309 | if (newinode) { | 343 | if (newinode) { |
310 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) | 344 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) |
311 | newinode->i_mode = mode; | 345 | newinode->i_mode = mode; |
312 | if ((oplock & CIFS_CREATE_ACTION) && | 346 | if ((*oplock & CIFS_CREATE_ACTION) && |
313 | (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) { | 347 | (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) { |
314 | newinode->i_uid = current_fsuid(); | 348 | newinode->i_uid = current_fsuid(); |
315 | if (inode->i_mode & S_ISGID) | 349 | if (inode->i_mode & S_ISGID) |
@@ -321,40 +355,139 @@ cifs_create_get_file_info: | |||
321 | } | 355 | } |
322 | 356 | ||
323 | cifs_create_set_dentry: | 357 | cifs_create_set_dentry: |
324 | if (rc == 0) | 358 | if (rc != 0) { |
325 | d_instantiate(direntry, newinode); | ||
326 | else | ||
327 | cFYI(1, "Create worked, get_inode_info failed rc = %d", rc); | 359 | cFYI(1, "Create worked, get_inode_info failed rc = %d", rc); |
360 | goto out; | ||
361 | } | ||
362 | d_drop(direntry); | ||
363 | d_add(direntry, newinode); | ||
328 | 364 | ||
329 | if (newinode && nd) { | 365 | /* ENOENT for create? How weird... */ |
330 | struct cifsFileInfo *pfile_info; | 366 | rc = -ENOENT; |
331 | struct file *filp; | 367 | if (!newinode) { |
368 | CIFSSMBClose(xid, tcon, *fileHandle); | ||
369 | goto out; | ||
370 | } | ||
371 | rc = 0; | ||
332 | 372 | ||
333 | filp = lookup_instantiate_filp(nd, direntry, generic_file_open); | 373 | out: |
334 | if (IS_ERR(filp)) { | 374 | kfree(buf); |
335 | rc = PTR_ERR(filp); | 375 | kfree(full_path); |
336 | CIFSSMBClose(xid, tcon, fileHandle); | 376 | return rc; |
337 | goto cifs_create_out; | 377 | } |
338 | } | ||
339 | 378 | ||
340 | pfile_info = cifs_new_fileinfo(fileHandle, filp, tlink, oplock); | 379 | int |
341 | if (pfile_info == NULL) { | 380 | cifs_atomic_open(struct inode *inode, struct dentry *direntry, |
342 | fput(filp); | 381 | struct file *file, unsigned oflags, umode_t mode, |
343 | CIFSSMBClose(xid, tcon, fileHandle); | 382 | int *opened) |
344 | rc = -ENOMEM; | 383 | { |
345 | } | 384 | int rc; |
346 | } else { | 385 | int xid; |
386 | struct tcon_link *tlink; | ||
387 | struct cifs_tcon *tcon; | ||
388 | __u16 fileHandle; | ||
389 | __u32 oplock; | ||
390 | struct file *filp; | ||
391 | struct cifsFileInfo *pfile_info; | ||
392 | |||
393 | /* Posix open is only called (at lookup time) for file create now. For | ||
394 | * opens (rather than creates), because we do not know if it is a file | ||
395 | * or directory yet, and current Samba no longer allows us to do posix | ||
396 | * open on dirs, we could end up wasting an open call on what turns out | ||
397 | * to be a dir. For file opens, we wait to call posix open till | ||
398 | * cifs_open. It could be added to atomic_open in the future but the | ||
399 | * performance tradeoff of the extra network request when EISDIR or | ||
400 | * EACCES is returned would have to be weighed against the 50% reduction | ||
401 | * in network traffic in the other paths. | ||
402 | */ | ||
403 | if (!(oflags & O_CREAT)) { | ||
404 | struct dentry *res = cifs_lookup(inode, direntry, 0); | ||
405 | if (IS_ERR(res)) | ||
406 | return PTR_ERR(res); | ||
407 | |||
408 | return finish_no_open(file, res); | ||
409 | } | ||
410 | |||
411 | rc = check_name(direntry); | ||
412 | if (rc) | ||
413 | return rc; | ||
414 | |||
415 | xid = GetXid(); | ||
416 | |||
417 | cFYI(1, "parent inode = 0x%p name is: %s and dentry = 0x%p", | ||
418 | inode, direntry->d_name.name, direntry); | ||
419 | |||
420 | tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb)); | ||
421 | filp = ERR_CAST(tlink); | ||
422 | if (IS_ERR(tlink)) | ||
423 | goto free_xid; | ||
424 | |||
425 | tcon = tlink_tcon(tlink); | ||
426 | |||
427 | rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, | ||
428 | &oplock, &fileHandle, opened); | ||
429 | |||
430 | if (rc) | ||
431 | goto out; | ||
432 | |||
433 | rc = finish_open(file, direntry, generic_file_open, opened); | ||
434 | if (rc) { | ||
347 | CIFSSMBClose(xid, tcon, fileHandle); | 435 | CIFSSMBClose(xid, tcon, fileHandle); |
436 | goto out; | ||
348 | } | 437 | } |
349 | 438 | ||
350 | cifs_create_out: | 439 | pfile_info = cifs_new_fileinfo(fileHandle, filp, tlink, oplock); |
351 | kfree(buf); | 440 | if (pfile_info == NULL) { |
352 | kfree(full_path); | 441 | CIFSSMBClose(xid, tcon, fileHandle); |
442 | fput(filp); | ||
443 | rc = -ENOMEM; | ||
444 | } | ||
445 | |||
446 | out: | ||
353 | cifs_put_tlink(tlink); | 447 | cifs_put_tlink(tlink); |
448 | free_xid: | ||
354 | FreeXid(xid); | 449 | FreeXid(xid); |
355 | return rc; | 450 | return rc; |
356 | } | 451 | } |
357 | 452 | ||
453 | int cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode, | ||
454 | bool excl) | ||
455 | { | ||
456 | int rc; | ||
457 | int xid = GetXid(); | ||
458 | /* | ||
459 | * BB below access is probably too much for mknod to request | ||
460 | * but we have to do query and setpathinfo so requesting | ||
461 | * less could fail (unless we want to request getatr and setatr | ||
462 | * permissions (only). At least for POSIX we do not have to | ||
463 | * request so much. | ||
464 | */ | ||
465 | unsigned oflags = O_EXCL | O_CREAT | O_RDWR; | ||
466 | struct tcon_link *tlink; | ||
467 | __u16 fileHandle; | ||
468 | __u32 oplock; | ||
469 | int created = FILE_CREATED; | ||
470 | |||
471 | cFYI(1, "cifs_create parent inode = 0x%p name is: %s and dentry = 0x%p", | ||
472 | inode, direntry->d_name.name, direntry); | ||
473 | |||
474 | tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb)); | ||
475 | rc = PTR_ERR(tlink); | ||
476 | if (IS_ERR(tlink)) | ||
477 | goto free_xid; | ||
478 | |||
479 | rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, | ||
480 | &oplock, &fileHandle, &created); | ||
481 | if (!rc) | ||
482 | CIFSSMBClose(xid, tlink_tcon(tlink), fileHandle); | ||
483 | |||
484 | cifs_put_tlink(tlink); | ||
485 | free_xid: | ||
486 | FreeXid(xid); | ||
487 | |||
488 | return rc; | ||
489 | } | ||
490 | |||
358 | int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode, | 491 | int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode, |
359 | dev_t device_number) | 492 | dev_t device_number) |
360 | { | 493 | { |
@@ -488,20 +621,15 @@ mknod_out: | |||
488 | 621 | ||
489 | struct dentry * | 622 | struct dentry * |
490 | cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | 623 | cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, |
491 | struct nameidata *nd) | 624 | unsigned int flags) |
492 | { | 625 | { |
493 | int xid; | 626 | int xid; |
494 | int rc = 0; /* to get around spurious gcc warning, set to zero here */ | 627 | int rc = 0; /* to get around spurious gcc warning, set to zero here */ |
495 | __u32 oplock; | ||
496 | __u16 fileHandle = 0; | ||
497 | bool posix_open = false; | ||
498 | struct cifs_sb_info *cifs_sb; | 628 | struct cifs_sb_info *cifs_sb; |
499 | struct tcon_link *tlink; | 629 | struct tcon_link *tlink; |
500 | struct cifs_tcon *pTcon; | 630 | struct cifs_tcon *pTcon; |
501 | struct cifsFileInfo *cfile; | ||
502 | struct inode *newInode = NULL; | 631 | struct inode *newInode = NULL; |
503 | char *full_path = NULL; | 632 | char *full_path = NULL; |
504 | struct file *filp; | ||
505 | 633 | ||
506 | xid = GetXid(); | 634 | xid = GetXid(); |
507 | 635 | ||
@@ -518,31 +646,9 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
518 | } | 646 | } |
519 | pTcon = tlink_tcon(tlink); | 647 | pTcon = tlink_tcon(tlink); |
520 | 648 | ||
521 | oplock = pTcon->ses->server->oplocks ? REQ_OPLOCK : 0; | 649 | rc = check_name(direntry); |
522 | 650 | if (rc) | |
523 | /* | ||
524 | * Don't allow the separator character in a path component. | ||
525 | * The VFS will not allow "/", but "\" is allowed by posix. | ||
526 | */ | ||
527 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) { | ||
528 | int i; | ||
529 | for (i = 0; i < direntry->d_name.len; i++) | ||
530 | if (direntry->d_name.name[i] == '\\') { | ||
531 | cFYI(1, "Invalid file name"); | ||
532 | rc = -EINVAL; | ||
533 | goto lookup_out; | ||
534 | } | ||
535 | } | ||
536 | |||
537 | /* | ||
538 | * O_EXCL: optimize away the lookup, but don't hash the dentry. Let | ||
539 | * the VFS handle the create. | ||
540 | */ | ||
541 | if (nd && (nd->flags & LOOKUP_EXCL)) { | ||
542 | d_instantiate(direntry, NULL); | ||
543 | rc = 0; | ||
544 | goto lookup_out; | 651 | goto lookup_out; |
545 | } | ||
546 | 652 | ||
547 | /* can not grab the rename sem here since it would | 653 | /* can not grab the rename sem here since it would |
548 | deadlock in the cases (beginning of sys_rename itself) | 654 | deadlock in the cases (beginning of sys_rename itself) |
@@ -560,80 +666,16 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
560 | } | 666 | } |
561 | cFYI(1, "Full path: %s inode = 0x%p", full_path, direntry->d_inode); | 667 | cFYI(1, "Full path: %s inode = 0x%p", full_path, direntry->d_inode); |
562 | 668 | ||
563 | /* Posix open is only called (at lookup time) for file create now. | ||
564 | * For opens (rather than creates), because we do not know if it | ||
565 | * is a file or directory yet, and current Samba no longer allows | ||
566 | * us to do posix open on dirs, we could end up wasting an open call | ||
567 | * on what turns out to be a dir. For file opens, we wait to call posix | ||
568 | * open till cifs_open. It could be added here (lookup) in the future | ||
569 | * but the performance tradeoff of the extra network request when EISDIR | ||
570 | * or EACCES is returned would have to be weighed against the 50% | ||
571 | * reduction in network traffic in the other paths. | ||
572 | */ | ||
573 | if (pTcon->unix_ext) { | 669 | if (pTcon->unix_ext) { |
574 | if (nd && !(nd->flags & LOOKUP_DIRECTORY) && | 670 | rc = cifs_get_inode_info_unix(&newInode, full_path, |
575 | (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open && | 671 | parent_dir_inode->i_sb, xid); |
576 | (nd->intent.open.file->f_flags & O_CREAT)) { | 672 | } else { |
577 | rc = cifs_posix_open(full_path, &newInode, | ||
578 | parent_dir_inode->i_sb, | ||
579 | nd->intent.open.create_mode, | ||
580 | nd->intent.open.file->f_flags, &oplock, | ||
581 | &fileHandle, xid); | ||
582 | /* | ||
583 | * The check below works around a bug in POSIX | ||
584 | * open in samba versions 3.3.1 and earlier where | ||
585 | * open could incorrectly fail with invalid parameter. | ||
586 | * If either that or op not supported returned, follow | ||
587 | * the normal lookup. | ||
588 | */ | ||
589 | switch (rc) { | ||
590 | case 0: | ||
591 | /* | ||
592 | * The server may allow us to open things like | ||
593 | * FIFOs, but the client isn't set up to deal | ||
594 | * with that. If it's not a regular file, just | ||
595 | * close it and proceed as if it were a normal | ||
596 | * lookup. | ||
597 | */ | ||
598 | if (newInode && !S_ISREG(newInode->i_mode)) { | ||
599 | CIFSSMBClose(xid, pTcon, fileHandle); | ||
600 | break; | ||
601 | } | ||
602 | case -ENOENT: | ||
603 | posix_open = true; | ||
604 | case -EOPNOTSUPP: | ||
605 | break; | ||
606 | default: | ||
607 | pTcon->broken_posix_open = true; | ||
608 | } | ||
609 | } | ||
610 | if (!posix_open) | ||
611 | rc = cifs_get_inode_info_unix(&newInode, full_path, | ||
612 | parent_dir_inode->i_sb, xid); | ||
613 | } else | ||
614 | rc = cifs_get_inode_info(&newInode, full_path, NULL, | 673 | rc = cifs_get_inode_info(&newInode, full_path, NULL, |
615 | parent_dir_inode->i_sb, xid, NULL); | 674 | parent_dir_inode->i_sb, xid, NULL); |
675 | } | ||
616 | 676 | ||
617 | if ((rc == 0) && (newInode != NULL)) { | 677 | if ((rc == 0) && (newInode != NULL)) { |
618 | d_add(direntry, newInode); | 678 | d_add(direntry, newInode); |
619 | if (posix_open) { | ||
620 | filp = lookup_instantiate_filp(nd, direntry, | ||
621 | generic_file_open); | ||
622 | if (IS_ERR(filp)) { | ||
623 | rc = PTR_ERR(filp); | ||
624 | CIFSSMBClose(xid, pTcon, fileHandle); | ||
625 | goto lookup_out; | ||
626 | } | ||
627 | |||
628 | cfile = cifs_new_fileinfo(fileHandle, filp, tlink, | ||
629 | oplock); | ||
630 | if (cfile == NULL) { | ||
631 | fput(filp); | ||
632 | CIFSSMBClose(xid, pTcon, fileHandle); | ||
633 | rc = -ENOMEM; | ||
634 | goto lookup_out; | ||
635 | } | ||
636 | } | ||
637 | /* since paths are not looked up by component - the parent | 679 | /* since paths are not looked up by component - the parent |
638 | directories are presumed to be good here */ | 680 | directories are presumed to be good here */ |
639 | renew_parental_timestamps(direntry); | 681 | renew_parental_timestamps(direntry); |
@@ -658,9 +700,9 @@ lookup_out: | |||
658 | } | 700 | } |
659 | 701 | ||
660 | static int | 702 | static int |
661 | cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) | 703 | cifs_d_revalidate(struct dentry *direntry, unsigned int flags) |
662 | { | 704 | { |
663 | if (nd && (nd->flags & LOOKUP_RCU)) | 705 | if (flags & LOOKUP_RCU) |
664 | return -ECHILD; | 706 | return -ECHILD; |
665 | 707 | ||
666 | if (direntry->d_inode) { | 708 | if (direntry->d_inode) { |
@@ -689,7 +731,7 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) | |||
689 | * This may be nfsd (or something), anyway, we can't see the | 731 | * This may be nfsd (or something), anyway, we can't see the |
690 | * intent of this. So, since this can be for creation, drop it. | 732 | * intent of this. So, since this can be for creation, drop it. |
691 | */ | 733 | */ |
692 | if (!nd) | 734 | if (!flags) |
693 | return 0; | 735 | return 0; |
694 | 736 | ||
695 | /* | 737 | /* |
@@ -697,7 +739,7 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) | |||
697 | * case sensitive name which is specified by user if this is | 739 | * case sensitive name which is specified by user if this is |
698 | * for creation. | 740 | * for creation. |
699 | */ | 741 | */ |
700 | if (nd->flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET)) | 742 | if (flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET)) |
701 | return 0; | 743 | return 0; |
702 | 744 | ||
703 | if (time_after(jiffies, direntry->d_time + HZ) || !lookupCacheEnabled) | 745 | if (time_after(jiffies, direntry->d_time + HZ) || !lookupCacheEnabled) |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 745da3d0653e..8e8bb49112ff 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -800,7 +800,7 @@ cifs_find_inode(struct inode *inode, void *opaque) | |||
800 | return 0; | 800 | return 0; |
801 | 801 | ||
802 | /* if it's not a directory or has no dentries, then flag it */ | 802 | /* if it's not a directory or has no dentries, then flag it */ |
803 | if (S_ISDIR(inode->i_mode) && !list_empty(&inode->i_dentry)) | 803 | if (S_ISDIR(inode->i_mode) && !hlist_empty(&inode->i_dentry)) |
804 | fattr->cf_flags |= CIFS_FATTR_INO_COLLISION; | 804 | fattr->cf_flags |= CIFS_FATTR_INO_COLLISION; |
805 | 805 | ||
806 | return 1; | 806 | return 1; |
@@ -825,9 +825,10 @@ static bool | |||
825 | inode_has_hashed_dentries(struct inode *inode) | 825 | inode_has_hashed_dentries(struct inode *inode) |
826 | { | 826 | { |
827 | struct dentry *dentry; | 827 | struct dentry *dentry; |
828 | struct hlist_node *p; | ||
828 | 829 | ||
829 | spin_lock(&inode->i_lock); | 830 | spin_lock(&inode->i_lock); |
830 | list_for_each_entry(dentry, &inode->i_dentry, d_alias) { | 831 | hlist_for_each_entry(dentry, p, &inode->i_dentry, d_alias) { |
831 | if (!d_unhashed(dentry) || IS_ROOT(dentry)) { | 832 | if (!d_unhashed(dentry) || IS_ROOT(dentry)) { |
832 | spin_unlock(&inode->i_lock); | 833 | spin_unlock(&inode->i_lock); |
833 | return true; | 834 | return true; |
diff --git a/fs/coda/cache.c b/fs/coda/cache.c index 690157876184..958ae0e0ff8c 100644 --- a/fs/coda/cache.c +++ b/fs/coda/cache.c | |||
@@ -89,17 +89,13 @@ int coda_cache_check(struct inode *inode, int mask) | |||
89 | /* this won't do any harm: just flag all children */ | 89 | /* this won't do any harm: just flag all children */ |
90 | static void coda_flag_children(struct dentry *parent, int flag) | 90 | static void coda_flag_children(struct dentry *parent, int flag) |
91 | { | 91 | { |
92 | struct list_head *child; | ||
93 | struct dentry *de; | 92 | struct dentry *de; |
94 | 93 | ||
95 | spin_lock(&parent->d_lock); | 94 | spin_lock(&parent->d_lock); |
96 | list_for_each(child, &parent->d_subdirs) | 95 | list_for_each_entry(de, &parent->d_subdirs, d_u.d_child) { |
97 | { | ||
98 | de = list_entry(child, struct dentry, d_u.d_child); | ||
99 | /* don't know what to do with negative dentries */ | 96 | /* don't know what to do with negative dentries */ |
100 | if ( ! de->d_inode ) | 97 | if (de->d_inode ) |
101 | continue; | 98 | coda_flag_inode(de->d_inode, flag); |
102 | coda_flag_inode(de->d_inode, flag); | ||
103 | } | 99 | } |
104 | spin_unlock(&parent->d_lock); | 100 | spin_unlock(&parent->d_lock); |
105 | return; | 101 | return; |
diff --git a/fs/coda/dir.c b/fs/coda/dir.c index 177515829062..49fe52d25600 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c | |||
@@ -30,8 +30,8 @@ | |||
30 | #include "coda_int.h" | 30 | #include "coda_int.h" |
31 | 31 | ||
32 | /* dir inode-ops */ | 32 | /* dir inode-ops */ |
33 | static int coda_create(struct inode *dir, struct dentry *new, umode_t mode, struct nameidata *nd); | 33 | static int coda_create(struct inode *dir, struct dentry *new, umode_t mode, bool excl); |
34 | static struct dentry *coda_lookup(struct inode *dir, struct dentry *target, struct nameidata *nd); | 34 | static struct dentry *coda_lookup(struct inode *dir, struct dentry *target, unsigned int flags); |
35 | static int coda_link(struct dentry *old_dentry, struct inode *dir_inode, | 35 | static int coda_link(struct dentry *old_dentry, struct inode *dir_inode, |
36 | struct dentry *entry); | 36 | struct dentry *entry); |
37 | static int coda_unlink(struct inode *dir_inode, struct dentry *entry); | 37 | static int coda_unlink(struct inode *dir_inode, struct dentry *entry); |
@@ -46,7 +46,7 @@ static int coda_rename(struct inode *old_inode, struct dentry *old_dentry, | |||
46 | static int coda_readdir(struct file *file, void *buf, filldir_t filldir); | 46 | static int coda_readdir(struct file *file, void *buf, filldir_t filldir); |
47 | 47 | ||
48 | /* dentry ops */ | 48 | /* dentry ops */ |
49 | static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd); | 49 | static int coda_dentry_revalidate(struct dentry *de, unsigned int flags); |
50 | static int coda_dentry_delete(const struct dentry *); | 50 | static int coda_dentry_delete(const struct dentry *); |
51 | 51 | ||
52 | /* support routines */ | 52 | /* support routines */ |
@@ -94,7 +94,7 @@ const struct file_operations coda_dir_operations = { | |||
94 | 94 | ||
95 | /* inode operations for directories */ | 95 | /* inode operations for directories */ |
96 | /* access routines: lookup, readlink, permission */ | 96 | /* access routines: lookup, readlink, permission */ |
97 | static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, struct nameidata *nd) | 97 | static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, unsigned int flags) |
98 | { | 98 | { |
99 | struct super_block *sb = dir->i_sb; | 99 | struct super_block *sb = dir->i_sb; |
100 | const char *name = entry->d_name.name; | 100 | const char *name = entry->d_name.name; |
@@ -188,7 +188,7 @@ static inline void coda_dir_drop_nlink(struct inode *dir) | |||
188 | } | 188 | } |
189 | 189 | ||
190 | /* creation routines: create, mknod, mkdir, link, symlink */ | 190 | /* creation routines: create, mknod, mkdir, link, symlink */ |
191 | static int coda_create(struct inode *dir, struct dentry *de, umode_t mode, struct nameidata *nd) | 191 | static int coda_create(struct inode *dir, struct dentry *de, umode_t mode, bool excl) |
192 | { | 192 | { |
193 | int error; | 193 | int error; |
194 | const char *name=de->d_name.name; | 194 | const char *name=de->d_name.name; |
@@ -536,12 +536,12 @@ out: | |||
536 | } | 536 | } |
537 | 537 | ||
538 | /* called when a cache lookup succeeds */ | 538 | /* called when a cache lookup succeeds */ |
539 | static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd) | 539 | static int coda_dentry_revalidate(struct dentry *de, unsigned int flags) |
540 | { | 540 | { |
541 | struct inode *inode; | 541 | struct inode *inode; |
542 | struct coda_inode_info *cii; | 542 | struct coda_inode_info *cii; |
543 | 543 | ||
544 | if (nd->flags & LOOKUP_RCU) | 544 | if (flags & LOOKUP_RCU) |
545 | return -ECHILD; | 545 | return -ECHILD; |
546 | 546 | ||
547 | inode = de->d_inode; | 547 | inode = de->d_inode; |
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 7e6c52d8a207..7414ae24a79b 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c | |||
@@ -442,7 +442,7 @@ static int configfs_attach_attr(struct configfs_dirent * sd, struct dentry * den | |||
442 | 442 | ||
443 | static struct dentry * configfs_lookup(struct inode *dir, | 443 | static struct dentry * configfs_lookup(struct inode *dir, |
444 | struct dentry *dentry, | 444 | struct dentry *dentry, |
445 | struct nameidata *nd) | 445 | unsigned int flags) |
446 | { | 446 | { |
447 | struct configfs_dirent * parent_sd = dentry->d_parent->d_fsdata; | 447 | struct configfs_dirent * parent_sd = dentry->d_parent->d_fsdata; |
448 | struct configfs_dirent * sd; | 448 | struct configfs_dirent * sd; |
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index d013c46402ed..28cca01ca9c9 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c | |||
@@ -417,7 +417,7 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
417 | /* | 417 | /* |
418 | * Lookup and fill in the inode data.. | 418 | * Lookup and fill in the inode data.. |
419 | */ | 419 | */ |
420 | static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | 420 | static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) |
421 | { | 421 | { |
422 | unsigned int offset = 0; | 422 | unsigned int offset = 0; |
423 | struct inode *inode = NULL; | 423 | struct inode *inode = NULL; |
diff --git a/fs/dcache.c b/fs/dcache.c index 40469044088d..8086636bf796 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -218,7 +218,7 @@ static void __d_free(struct rcu_head *head) | |||
218 | { | 218 | { |
219 | struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu); | 219 | struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu); |
220 | 220 | ||
221 | WARN_ON(!list_empty(&dentry->d_alias)); | 221 | WARN_ON(!hlist_unhashed(&dentry->d_alias)); |
222 | if (dname_external(dentry)) | 222 | if (dname_external(dentry)) |
223 | kfree(dentry->d_name.name); | 223 | kfree(dentry->d_name.name); |
224 | kmem_cache_free(dentry_cache, dentry); | 224 | kmem_cache_free(dentry_cache, dentry); |
@@ -267,7 +267,7 @@ static void dentry_iput(struct dentry * dentry) | |||
267 | struct inode *inode = dentry->d_inode; | 267 | struct inode *inode = dentry->d_inode; |
268 | if (inode) { | 268 | if (inode) { |
269 | dentry->d_inode = NULL; | 269 | dentry->d_inode = NULL; |
270 | list_del_init(&dentry->d_alias); | 270 | hlist_del_init(&dentry->d_alias); |
271 | spin_unlock(&dentry->d_lock); | 271 | spin_unlock(&dentry->d_lock); |
272 | spin_unlock(&inode->i_lock); | 272 | spin_unlock(&inode->i_lock); |
273 | if (!inode->i_nlink) | 273 | if (!inode->i_nlink) |
@@ -291,7 +291,7 @@ static void dentry_unlink_inode(struct dentry * dentry) | |||
291 | { | 291 | { |
292 | struct inode *inode = dentry->d_inode; | 292 | struct inode *inode = dentry->d_inode; |
293 | dentry->d_inode = NULL; | 293 | dentry->d_inode = NULL; |
294 | list_del_init(&dentry->d_alias); | 294 | hlist_del_init(&dentry->d_alias); |
295 | dentry_rcuwalk_barrier(dentry); | 295 | dentry_rcuwalk_barrier(dentry); |
296 | spin_unlock(&dentry->d_lock); | 296 | spin_unlock(&dentry->d_lock); |
297 | spin_unlock(&inode->i_lock); | 297 | spin_unlock(&inode->i_lock); |
@@ -699,10 +699,11 @@ EXPORT_SYMBOL(dget_parent); | |||
699 | static struct dentry *__d_find_alias(struct inode *inode, int want_discon) | 699 | static struct dentry *__d_find_alias(struct inode *inode, int want_discon) |
700 | { | 700 | { |
701 | struct dentry *alias, *discon_alias; | 701 | struct dentry *alias, *discon_alias; |
702 | struct hlist_node *p; | ||
702 | 703 | ||
703 | again: | 704 | again: |
704 | discon_alias = NULL; | 705 | discon_alias = NULL; |
705 | list_for_each_entry(alias, &inode->i_dentry, d_alias) { | 706 | hlist_for_each_entry(alias, p, &inode->i_dentry, d_alias) { |
706 | spin_lock(&alias->d_lock); | 707 | spin_lock(&alias->d_lock); |
707 | if (S_ISDIR(inode->i_mode) || !d_unhashed(alias)) { | 708 | if (S_ISDIR(inode->i_mode) || !d_unhashed(alias)) { |
708 | if (IS_ROOT(alias) && | 709 | if (IS_ROOT(alias) && |
@@ -737,7 +738,7 @@ struct dentry *d_find_alias(struct inode *inode) | |||
737 | { | 738 | { |
738 | struct dentry *de = NULL; | 739 | struct dentry *de = NULL; |
739 | 740 | ||
740 | if (!list_empty(&inode->i_dentry)) { | 741 | if (!hlist_empty(&inode->i_dentry)) { |
741 | spin_lock(&inode->i_lock); | 742 | spin_lock(&inode->i_lock); |
742 | de = __d_find_alias(inode, 0); | 743 | de = __d_find_alias(inode, 0); |
743 | spin_unlock(&inode->i_lock); | 744 | spin_unlock(&inode->i_lock); |
@@ -753,9 +754,10 @@ EXPORT_SYMBOL(d_find_alias); | |||
753 | void d_prune_aliases(struct inode *inode) | 754 | void d_prune_aliases(struct inode *inode) |
754 | { | 755 | { |
755 | struct dentry *dentry; | 756 | struct dentry *dentry; |
757 | struct hlist_node *p; | ||
756 | restart: | 758 | restart: |
757 | spin_lock(&inode->i_lock); | 759 | spin_lock(&inode->i_lock); |
758 | list_for_each_entry(dentry, &inode->i_dentry, d_alias) { | 760 | hlist_for_each_entry(dentry, p, &inode->i_dentry, d_alias) { |
759 | spin_lock(&dentry->d_lock); | 761 | spin_lock(&dentry->d_lock); |
760 | if (!dentry->d_count) { | 762 | if (!dentry->d_count) { |
761 | __dget_dlock(dentry); | 763 | __dget_dlock(dentry); |
@@ -977,7 +979,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry) | |||
977 | inode = dentry->d_inode; | 979 | inode = dentry->d_inode; |
978 | if (inode) { | 980 | if (inode) { |
979 | dentry->d_inode = NULL; | 981 | dentry->d_inode = NULL; |
980 | list_del_init(&dentry->d_alias); | 982 | hlist_del_init(&dentry->d_alias); |
981 | if (dentry->d_op && dentry->d_op->d_iput) | 983 | if (dentry->d_op && dentry->d_op->d_iput) |
982 | dentry->d_op->d_iput(dentry, inode); | 984 | dentry->d_op->d_iput(dentry, inode); |
983 | else | 985 | else |
@@ -1312,7 +1314,7 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name) | |||
1312 | INIT_HLIST_BL_NODE(&dentry->d_hash); | 1314 | INIT_HLIST_BL_NODE(&dentry->d_hash); |
1313 | INIT_LIST_HEAD(&dentry->d_lru); | 1315 | INIT_LIST_HEAD(&dentry->d_lru); |
1314 | INIT_LIST_HEAD(&dentry->d_subdirs); | 1316 | INIT_LIST_HEAD(&dentry->d_subdirs); |
1315 | INIT_LIST_HEAD(&dentry->d_alias); | 1317 | INIT_HLIST_NODE(&dentry->d_alias); |
1316 | INIT_LIST_HEAD(&dentry->d_u.d_child); | 1318 | INIT_LIST_HEAD(&dentry->d_u.d_child); |
1317 | d_set_d_op(dentry, dentry->d_sb->s_d_op); | 1319 | d_set_d_op(dentry, dentry->d_sb->s_d_op); |
1318 | 1320 | ||
@@ -1400,7 +1402,7 @@ static void __d_instantiate(struct dentry *dentry, struct inode *inode) | |||
1400 | if (inode) { | 1402 | if (inode) { |
1401 | if (unlikely(IS_AUTOMOUNT(inode))) | 1403 | if (unlikely(IS_AUTOMOUNT(inode))) |
1402 | dentry->d_flags |= DCACHE_NEED_AUTOMOUNT; | 1404 | dentry->d_flags |= DCACHE_NEED_AUTOMOUNT; |
1403 | list_add(&dentry->d_alias, &inode->i_dentry); | 1405 | hlist_add_head(&dentry->d_alias, &inode->i_dentry); |
1404 | } | 1406 | } |
1405 | dentry->d_inode = inode; | 1407 | dentry->d_inode = inode; |
1406 | dentry_rcuwalk_barrier(dentry); | 1408 | dentry_rcuwalk_barrier(dentry); |
@@ -1425,7 +1427,7 @@ static void __d_instantiate(struct dentry *dentry, struct inode *inode) | |||
1425 | 1427 | ||
1426 | void d_instantiate(struct dentry *entry, struct inode * inode) | 1428 | void d_instantiate(struct dentry *entry, struct inode * inode) |
1427 | { | 1429 | { |
1428 | BUG_ON(!list_empty(&entry->d_alias)); | 1430 | BUG_ON(!hlist_unhashed(&entry->d_alias)); |
1429 | if (inode) | 1431 | if (inode) |
1430 | spin_lock(&inode->i_lock); | 1432 | spin_lock(&inode->i_lock); |
1431 | __d_instantiate(entry, inode); | 1433 | __d_instantiate(entry, inode); |
@@ -1458,13 +1460,14 @@ static struct dentry *__d_instantiate_unique(struct dentry *entry, | |||
1458 | int len = entry->d_name.len; | 1460 | int len = entry->d_name.len; |
1459 | const char *name = entry->d_name.name; | 1461 | const char *name = entry->d_name.name; |
1460 | unsigned int hash = entry->d_name.hash; | 1462 | unsigned int hash = entry->d_name.hash; |
1463 | struct hlist_node *p; | ||
1461 | 1464 | ||
1462 | if (!inode) { | 1465 | if (!inode) { |
1463 | __d_instantiate(entry, NULL); | 1466 | __d_instantiate(entry, NULL); |
1464 | return NULL; | 1467 | return NULL; |
1465 | } | 1468 | } |
1466 | 1469 | ||
1467 | list_for_each_entry(alias, &inode->i_dentry, d_alias) { | 1470 | hlist_for_each_entry(alias, p, &inode->i_dentry, d_alias) { |
1468 | /* | 1471 | /* |
1469 | * Don't need alias->d_lock here, because aliases with | 1472 | * Don't need alias->d_lock here, because aliases with |
1470 | * d_parent == entry->d_parent are not subject to name or | 1473 | * d_parent == entry->d_parent are not subject to name or |
@@ -1490,7 +1493,7 @@ struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode) | |||
1490 | { | 1493 | { |
1491 | struct dentry *result; | 1494 | struct dentry *result; |
1492 | 1495 | ||
1493 | BUG_ON(!list_empty(&entry->d_alias)); | 1496 | BUG_ON(!hlist_unhashed(&entry->d_alias)); |
1494 | 1497 | ||
1495 | if (inode) | 1498 | if (inode) |
1496 | spin_lock(&inode->i_lock); | 1499 | spin_lock(&inode->i_lock); |
@@ -1531,9 +1534,9 @@ static struct dentry * __d_find_any_alias(struct inode *inode) | |||
1531 | { | 1534 | { |
1532 | struct dentry *alias; | 1535 | struct dentry *alias; |
1533 | 1536 | ||
1534 | if (list_empty(&inode->i_dentry)) | 1537 | if (hlist_empty(&inode->i_dentry)) |
1535 | return NULL; | 1538 | return NULL; |
1536 | alias = list_first_entry(&inode->i_dentry, struct dentry, d_alias); | 1539 | alias = hlist_entry(inode->i_dentry.first, struct dentry, d_alias); |
1537 | __dget(alias); | 1540 | __dget(alias); |
1538 | return alias; | 1541 | return alias; |
1539 | } | 1542 | } |
@@ -1607,7 +1610,7 @@ struct dentry *d_obtain_alias(struct inode *inode) | |||
1607 | spin_lock(&tmp->d_lock); | 1610 | spin_lock(&tmp->d_lock); |
1608 | tmp->d_inode = inode; | 1611 | tmp->d_inode = inode; |
1609 | tmp->d_flags |= DCACHE_DISCONNECTED; | 1612 | tmp->d_flags |= DCACHE_DISCONNECTED; |
1610 | list_add(&tmp->d_alias, &inode->i_dentry); | 1613 | hlist_add_head(&tmp->d_alias, &inode->i_dentry); |
1611 | hlist_bl_lock(&tmp->d_sb->s_anon); | 1614 | hlist_bl_lock(&tmp->d_sb->s_anon); |
1612 | hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon); | 1615 | hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon); |
1613 | hlist_bl_unlock(&tmp->d_sb->s_anon); | 1616 | hlist_bl_unlock(&tmp->d_sb->s_anon); |
@@ -2384,14 +2387,13 @@ static struct dentry *__d_unalias(struct inode *inode, | |||
2384 | struct dentry *dentry, struct dentry *alias) | 2387 | struct dentry *dentry, struct dentry *alias) |
2385 | { | 2388 | { |
2386 | struct mutex *m1 = NULL, *m2 = NULL; | 2389 | struct mutex *m1 = NULL, *m2 = NULL; |
2387 | struct dentry *ret; | 2390 | struct dentry *ret = ERR_PTR(-EBUSY); |
2388 | 2391 | ||
2389 | /* If alias and dentry share a parent, then no extra locks required */ | 2392 | /* If alias and dentry share a parent, then no extra locks required */ |
2390 | if (alias->d_parent == dentry->d_parent) | 2393 | if (alias->d_parent == dentry->d_parent) |
2391 | goto out_unalias; | 2394 | goto out_unalias; |
2392 | 2395 | ||
2393 | /* See lock_rename() */ | 2396 | /* See lock_rename() */ |
2394 | ret = ERR_PTR(-EBUSY); | ||
2395 | if (!mutex_trylock(&dentry->d_sb->s_vfs_rename_mutex)) | 2397 | if (!mutex_trylock(&dentry->d_sb->s_vfs_rename_mutex)) |
2396 | goto out_err; | 2398 | goto out_err; |
2397 | m1 = &dentry->d_sb->s_vfs_rename_mutex; | 2399 | m1 = &dentry->d_sb->s_vfs_rename_mutex; |
@@ -2399,8 +2401,10 @@ static struct dentry *__d_unalias(struct inode *inode, | |||
2399 | goto out_err; | 2401 | goto out_err; |
2400 | m2 = &alias->d_parent->d_inode->i_mutex; | 2402 | m2 = &alias->d_parent->d_inode->i_mutex; |
2401 | out_unalias: | 2403 | out_unalias: |
2402 | __d_move(alias, dentry); | 2404 | if (likely(!d_mountpoint(alias))) { |
2403 | ret = alias; | 2405 | __d_move(alias, dentry); |
2406 | ret = alias; | ||
2407 | } | ||
2404 | out_err: | 2408 | out_err: |
2405 | spin_unlock(&inode->i_lock); | 2409 | spin_unlock(&inode->i_lock); |
2406 | if (m2) | 2410 | if (m2) |
@@ -2622,7 +2626,7 @@ global_root: | |||
2622 | if (!slash) | 2626 | if (!slash) |
2623 | error = prepend(buffer, buflen, "/", 1); | 2627 | error = prepend(buffer, buflen, "/", 1); |
2624 | if (!error) | 2628 | if (!error) |
2625 | error = real_mount(vfsmnt)->mnt_ns ? 1 : 2; | 2629 | error = is_mounted(vfsmnt) ? 1 : 2; |
2626 | goto out; | 2630 | goto out; |
2627 | } | 2631 | } |
2628 | 2632 | ||
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index b80bc846a15a..d17c20fd74e6 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c | |||
@@ -54,13 +54,12 @@ static struct inode *debugfs_get_inode(struct super_block *sb, umode_t mode, dev | |||
54 | break; | 54 | break; |
55 | case S_IFLNK: | 55 | case S_IFLNK: |
56 | inode->i_op = &debugfs_link_operations; | 56 | inode->i_op = &debugfs_link_operations; |
57 | inode->i_fop = fops; | ||
58 | inode->i_private = data; | 57 | inode->i_private = data; |
59 | break; | 58 | break; |
60 | case S_IFDIR: | 59 | case S_IFDIR: |
61 | inode->i_op = &simple_dir_inode_operations; | 60 | inode->i_op = &simple_dir_inode_operations; |
62 | inode->i_fop = fops ? fops : &simple_dir_operations; | 61 | inode->i_fop = &simple_dir_operations; |
63 | inode->i_private = data; | 62 | inode->i_private = NULL; |
64 | 63 | ||
65 | /* directory inodes start off with i_nlink == 2 | 64 | /* directory inodes start off with i_nlink == 2 |
66 | * (for "." entry) */ | 65 | * (for "." entry) */ |
@@ -91,13 +90,12 @@ static int debugfs_mknod(struct inode *dir, struct dentry *dentry, | |||
91 | return error; | 90 | return error; |
92 | } | 91 | } |
93 | 92 | ||
94 | static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode, | 93 | static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) |
95 | void *data, const struct file_operations *fops) | ||
96 | { | 94 | { |
97 | int res; | 95 | int res; |
98 | 96 | ||
99 | mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR; | 97 | mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR; |
100 | res = debugfs_mknod(dir, dentry, mode, 0, data, fops); | 98 | res = debugfs_mknod(dir, dentry, mode, 0, NULL, NULL); |
101 | if (!res) { | 99 | if (!res) { |
102 | inc_nlink(dir); | 100 | inc_nlink(dir); |
103 | fsnotify_mkdir(dir, dentry); | 101 | fsnotify_mkdir(dir, dentry); |
@@ -106,10 +104,10 @@ static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode, | |||
106 | } | 104 | } |
107 | 105 | ||
108 | static int debugfs_link(struct inode *dir, struct dentry *dentry, umode_t mode, | 106 | static int debugfs_link(struct inode *dir, struct dentry *dentry, umode_t mode, |
109 | void *data, const struct file_operations *fops) | 107 | void *data) |
110 | { | 108 | { |
111 | mode = (mode & S_IALLUGO) | S_IFLNK; | 109 | mode = (mode & S_IALLUGO) | S_IFLNK; |
112 | return debugfs_mknod(dir, dentry, mode, 0, data, fops); | 110 | return debugfs_mknod(dir, dentry, mode, 0, data, NULL); |
113 | } | 111 | } |
114 | 112 | ||
115 | static int debugfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 113 | static int debugfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
@@ -293,13 +291,19 @@ static struct file_system_type debug_fs_type = { | |||
293 | .kill_sb = kill_litter_super, | 291 | .kill_sb = kill_litter_super, |
294 | }; | 292 | }; |
295 | 293 | ||
296 | static int debugfs_create_by_name(const char *name, umode_t mode, | 294 | struct dentry *__create_file(const char *name, umode_t mode, |
297 | struct dentry *parent, | 295 | struct dentry *parent, void *data, |
298 | struct dentry **dentry, | 296 | const struct file_operations *fops) |
299 | void *data, | ||
300 | const struct file_operations *fops) | ||
301 | { | 297 | { |
302 | int error = 0; | 298 | struct dentry *dentry = NULL; |
299 | int error; | ||
300 | |||
301 | pr_debug("debugfs: creating file '%s'\n",name); | ||
302 | |||
303 | error = simple_pin_fs(&debug_fs_type, &debugfs_mount, | ||
304 | &debugfs_mount_count); | ||
305 | if (error) | ||
306 | goto exit; | ||
303 | 307 | ||
304 | /* If the parent is not specified, we create it in the root. | 308 | /* If the parent is not specified, we create it in the root. |
305 | * We need the root dentry to do this, which is in the super | 309 | * We need the root dentry to do this, which is in the super |
@@ -309,30 +313,35 @@ static int debugfs_create_by_name(const char *name, umode_t mode, | |||
309 | if (!parent) | 313 | if (!parent) |
310 | parent = debugfs_mount->mnt_root; | 314 | parent = debugfs_mount->mnt_root; |
311 | 315 | ||
312 | *dentry = NULL; | 316 | dentry = NULL; |
313 | mutex_lock(&parent->d_inode->i_mutex); | 317 | mutex_lock(&parent->d_inode->i_mutex); |
314 | *dentry = lookup_one_len(name, parent, strlen(name)); | 318 | dentry = lookup_one_len(name, parent, strlen(name)); |
315 | if (!IS_ERR(*dentry)) { | 319 | if (!IS_ERR(dentry)) { |
316 | switch (mode & S_IFMT) { | 320 | switch (mode & S_IFMT) { |
317 | case S_IFDIR: | 321 | case S_IFDIR: |
318 | error = debugfs_mkdir(parent->d_inode, *dentry, mode, | 322 | error = debugfs_mkdir(parent->d_inode, dentry, mode); |
319 | data, fops); | 323 | |
320 | break; | 324 | break; |
321 | case S_IFLNK: | 325 | case S_IFLNK: |
322 | error = debugfs_link(parent->d_inode, *dentry, mode, | 326 | error = debugfs_link(parent->d_inode, dentry, mode, |
323 | data, fops); | 327 | data); |
324 | break; | 328 | break; |
325 | default: | 329 | default: |
326 | error = debugfs_create(parent->d_inode, *dentry, mode, | 330 | error = debugfs_create(parent->d_inode, dentry, mode, |
327 | data, fops); | 331 | data, fops); |
328 | break; | 332 | break; |
329 | } | 333 | } |
330 | dput(*dentry); | 334 | dput(dentry); |
331 | } else | 335 | } else |
332 | error = PTR_ERR(*dentry); | 336 | error = PTR_ERR(dentry); |
333 | mutex_unlock(&parent->d_inode->i_mutex); | 337 | mutex_unlock(&parent->d_inode->i_mutex); |
334 | 338 | ||
335 | return error; | 339 | if (error) { |
340 | dentry = NULL; | ||
341 | simple_release_fs(&debugfs_mount, &debugfs_mount_count); | ||
342 | } | ||
343 | exit: | ||
344 | return dentry; | ||
336 | } | 345 | } |
337 | 346 | ||
338 | /** | 347 | /** |
@@ -365,25 +374,15 @@ struct dentry *debugfs_create_file(const char *name, umode_t mode, | |||
365 | struct dentry *parent, void *data, | 374 | struct dentry *parent, void *data, |
366 | const struct file_operations *fops) | 375 | const struct file_operations *fops) |
367 | { | 376 | { |
368 | struct dentry *dentry = NULL; | 377 | switch (mode & S_IFMT) { |
369 | int error; | 378 | case S_IFREG: |
370 | 379 | case 0: | |
371 | pr_debug("debugfs: creating file '%s'\n",name); | 380 | break; |
372 | 381 | default: | |
373 | error = simple_pin_fs(&debug_fs_type, &debugfs_mount, | 382 | BUG(); |
374 | &debugfs_mount_count); | ||
375 | if (error) | ||
376 | goto exit; | ||
377 | |||
378 | error = debugfs_create_by_name(name, mode, parent, &dentry, | ||
379 | data, fops); | ||
380 | if (error) { | ||
381 | dentry = NULL; | ||
382 | simple_release_fs(&debugfs_mount, &debugfs_mount_count); | ||
383 | goto exit; | ||
384 | } | 383 | } |
385 | exit: | 384 | |
386 | return dentry; | 385 | return __create_file(name, mode, parent, data, fops); |
387 | } | 386 | } |
388 | EXPORT_SYMBOL_GPL(debugfs_create_file); | 387 | EXPORT_SYMBOL_GPL(debugfs_create_file); |
389 | 388 | ||
@@ -407,8 +406,7 @@ EXPORT_SYMBOL_GPL(debugfs_create_file); | |||
407 | */ | 406 | */ |
408 | struct dentry *debugfs_create_dir(const char *name, struct dentry *parent) | 407 | struct dentry *debugfs_create_dir(const char *name, struct dentry *parent) |
409 | { | 408 | { |
410 | return debugfs_create_file(name, | 409 | return __create_file(name, S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO, |
411 | S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO, | ||
412 | parent, NULL, NULL); | 410 | parent, NULL, NULL); |
413 | } | 411 | } |
414 | EXPORT_SYMBOL_GPL(debugfs_create_dir); | 412 | EXPORT_SYMBOL_GPL(debugfs_create_dir); |
@@ -446,8 +444,7 @@ struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent, | |||
446 | if (!link) | 444 | if (!link) |
447 | return NULL; | 445 | return NULL; |
448 | 446 | ||
449 | result = debugfs_create_file(name, S_IFLNK | S_IRWXUGO, parent, link, | 447 | result = __create_file(name, S_IFLNK | S_IRWXUGO, parent, link, NULL); |
450 | NULL); | ||
451 | if (!result) | 448 | if (!result) |
452 | kfree(link); | 449 | kfree(link); |
453 | return result; | 450 | return result; |
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index 979c1e309c73..14afbabe6546 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c | |||
@@ -439,15 +439,15 @@ static struct dentry *devpts_mount(struct file_system_type *fs_type, | |||
439 | return ERR_PTR(error); | 439 | return ERR_PTR(error); |
440 | 440 | ||
441 | if (opts.newinstance) | 441 | if (opts.newinstance) |
442 | s = sget(fs_type, NULL, set_anon_super, NULL); | 442 | s = sget(fs_type, NULL, set_anon_super, flags, NULL); |
443 | else | 443 | else |
444 | s = sget(fs_type, compare_init_pts_sb, set_anon_super, NULL); | 444 | s = sget(fs_type, compare_init_pts_sb, set_anon_super, flags, |
445 | NULL); | ||
445 | 446 | ||
446 | if (IS_ERR(s)) | 447 | if (IS_ERR(s)) |
447 | return ERR_CAST(s); | 448 | return ERR_CAST(s); |
448 | 449 | ||
449 | if (!s->s_root) { | 450 | if (!s->s_root) { |
450 | s->s_flags = flags; | ||
451 | error = devpts_fill_super(s, data, flags & MS_SILENT ? 1 : 0); | 451 | error = devpts_fill_super(s, data, flags & MS_SILENT ? 1 : 0); |
452 | if (error) | 452 | if (error) |
453 | goto out_undo_sget; | 453 | goto out_undo_sget; |
diff --git a/fs/direct-io.c b/fs/direct-io.c index 0c85fae37666..1faf4cb56f39 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c | |||
@@ -1258,7 +1258,7 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, | |||
1258 | */ | 1258 | */ |
1259 | BUG_ON(retval == -EIOCBQUEUED); | 1259 | BUG_ON(retval == -EIOCBQUEUED); |
1260 | if (dio->is_async && retval == 0 && dio->result && | 1260 | if (dio->is_async && retval == 0 && dio->result && |
1261 | ((rw & READ) || (dio->result == sdio.size))) | 1261 | ((rw == READ) || (dio->result == sdio.size))) |
1262 | retval = -EIOCBQUEUED; | 1262 | retval = -EIOCBQUEUED; |
1263 | 1263 | ||
1264 | if (retval != -EIOCBQUEUED) | 1264 | if (retval != -EIOCBQUEUED) |
diff --git a/fs/ecryptfs/dentry.c b/fs/ecryptfs/dentry.c index 534c1d46e69e..1b5d9af937df 100644 --- a/fs/ecryptfs/dentry.c +++ b/fs/ecryptfs/dentry.c | |||
@@ -32,7 +32,7 @@ | |||
32 | /** | 32 | /** |
33 | * ecryptfs_d_revalidate - revalidate an ecryptfs dentry | 33 | * ecryptfs_d_revalidate - revalidate an ecryptfs dentry |
34 | * @dentry: The ecryptfs dentry | 34 | * @dentry: The ecryptfs dentry |
35 | * @nd: The associated nameidata | 35 | * @flags: lookup flags |
36 | * | 36 | * |
37 | * Called when the VFS needs to revalidate a dentry. This | 37 | * Called when the VFS needs to revalidate a dentry. This |
38 | * is called whenever a name lookup finds a dentry in the | 38 | * is called whenever a name lookup finds a dentry in the |
@@ -42,32 +42,20 @@ | |||
42 | * Returns 1 if valid, 0 otherwise. | 42 | * Returns 1 if valid, 0 otherwise. |
43 | * | 43 | * |
44 | */ | 44 | */ |
45 | static int ecryptfs_d_revalidate(struct dentry *dentry, struct nameidata *nd) | 45 | static int ecryptfs_d_revalidate(struct dentry *dentry, unsigned int flags) |
46 | { | 46 | { |
47 | struct dentry *lower_dentry; | 47 | struct dentry *lower_dentry; |
48 | struct vfsmount *lower_mnt; | 48 | struct vfsmount *lower_mnt; |
49 | struct dentry *dentry_save = NULL; | ||
50 | struct vfsmount *vfsmount_save = NULL; | ||
51 | int rc = 1; | 49 | int rc = 1; |
52 | 50 | ||
53 | if (nd && nd->flags & LOOKUP_RCU) | 51 | if (flags & LOOKUP_RCU) |
54 | return -ECHILD; | 52 | return -ECHILD; |
55 | 53 | ||
56 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | 54 | lower_dentry = ecryptfs_dentry_to_lower(dentry); |
57 | lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); | 55 | lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); |
58 | if (!lower_dentry->d_op || !lower_dentry->d_op->d_revalidate) | 56 | if (!lower_dentry->d_op || !lower_dentry->d_op->d_revalidate) |
59 | goto out; | 57 | goto out; |
60 | if (nd) { | 58 | rc = lower_dentry->d_op->d_revalidate(lower_dentry, flags); |
61 | dentry_save = nd->path.dentry; | ||
62 | vfsmount_save = nd->path.mnt; | ||
63 | nd->path.dentry = lower_dentry; | ||
64 | nd->path.mnt = lower_mnt; | ||
65 | } | ||
66 | rc = lower_dentry->d_op->d_revalidate(lower_dentry, nd); | ||
67 | if (nd) { | ||
68 | nd->path.dentry = dentry_save; | ||
69 | nd->path.mnt = vfsmount_save; | ||
70 | } | ||
71 | if (dentry->d_inode) { | 59 | if (dentry->d_inode) { |
72 | struct inode *lower_inode = | 60 | struct inode *lower_inode = |
73 | ecryptfs_inode_to_lower(dentry->d_inode); | 61 | ecryptfs_inode_to_lower(dentry->d_inode); |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index a07441a0a878..da52cdbe8388 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -173,7 +173,7 @@ ecryptfs_do_create(struct inode *directory_inode, | |||
173 | inode = ERR_CAST(lower_dir_dentry); | 173 | inode = ERR_CAST(lower_dir_dentry); |
174 | goto out; | 174 | goto out; |
175 | } | 175 | } |
176 | rc = vfs_create(lower_dir_dentry->d_inode, lower_dentry, mode, NULL); | 176 | rc = vfs_create(lower_dir_dentry->d_inode, lower_dentry, mode, true); |
177 | if (rc) { | 177 | if (rc) { |
178 | printk(KERN_ERR "%s: Failure to create dentry in lower fs; " | 178 | printk(KERN_ERR "%s: Failure to create dentry in lower fs; " |
179 | "rc = [%d]\n", __func__, rc); | 179 | "rc = [%d]\n", __func__, rc); |
@@ -240,7 +240,6 @@ out: | |||
240 | * @dir: The inode of the directory in which to create the file. | 240 | * @dir: The inode of the directory in which to create the file. |
241 | * @dentry: The eCryptfs dentry | 241 | * @dentry: The eCryptfs dentry |
242 | * @mode: The mode of the new file. | 242 | * @mode: The mode of the new file. |
243 | * @nd: nameidata | ||
244 | * | 243 | * |
245 | * Creates a new file. | 244 | * Creates a new file. |
246 | * | 245 | * |
@@ -248,7 +247,7 @@ out: | |||
248 | */ | 247 | */ |
249 | static int | 248 | static int |
250 | ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry, | 249 | ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry, |
251 | umode_t mode, struct nameidata *nd) | 250 | umode_t mode, bool excl) |
252 | { | 251 | { |
253 | struct inode *ecryptfs_inode; | 252 | struct inode *ecryptfs_inode; |
254 | int rc; | 253 | int rc; |
@@ -374,7 +373,7 @@ static int ecryptfs_lookup_interpose(struct dentry *dentry, | |||
374 | */ | 373 | */ |
375 | static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | 374 | static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, |
376 | struct dentry *ecryptfs_dentry, | 375 | struct dentry *ecryptfs_dentry, |
377 | struct nameidata *ecryptfs_nd) | 376 | unsigned int flags) |
378 | { | 377 | { |
379 | char *encrypted_and_encoded_name = NULL; | 378 | char *encrypted_and_encoded_name = NULL; |
380 | size_t encrypted_and_encoded_name_size; | 379 | size_t encrypted_and_encoded_name_size; |
diff --git a/fs/ecryptfs/kthread.c b/fs/ecryptfs/kthread.c index 69f994a7d524..0dbe58a8b172 100644 --- a/fs/ecryptfs/kthread.c +++ b/fs/ecryptfs/kthread.c | |||
@@ -149,7 +149,7 @@ int ecryptfs_privileged_open(struct file **lower_file, | |||
149 | (*lower_file) = dentry_open(lower_dentry, lower_mnt, flags, cred); | 149 | (*lower_file) = dentry_open(lower_dentry, lower_mnt, flags, cred); |
150 | if (!IS_ERR(*lower_file)) | 150 | if (!IS_ERR(*lower_file)) |
151 | goto out; | 151 | goto out; |
152 | if (flags & O_RDONLY) { | 152 | if ((flags & O_ACCMODE) == O_RDONLY) { |
153 | rc = PTR_ERR((*lower_file)); | 153 | rc = PTR_ERR((*lower_file)); |
154 | goto out; | 154 | goto out; |
155 | } | 155 | } |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 68954937a071..7edeb3d893c1 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -499,13 +499,12 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags | |||
499 | goto out; | 499 | goto out; |
500 | } | 500 | } |
501 | 501 | ||
502 | s = sget(fs_type, NULL, set_anon_super, NULL); | 502 | s = sget(fs_type, NULL, set_anon_super, flags, NULL); |
503 | if (IS_ERR(s)) { | 503 | if (IS_ERR(s)) { |
504 | rc = PTR_ERR(s); | 504 | rc = PTR_ERR(s); |
505 | goto out; | 505 | goto out; |
506 | } | 506 | } |
507 | 507 | ||
508 | s->s_flags = flags; | ||
509 | rc = bdi_setup_and_register(&sbi->bdi, "ecryptfs", BDI_CAP_MAP_COPY); | 508 | rc = bdi_setup_and_register(&sbi->bdi, "ecryptfs", BDI_CAP_MAP_COPY); |
510 | if (rc) | 509 | if (rc) |
511 | goto out1; | 510 | goto out1; |
diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c index 3a06f4043df4..c0038f6566d4 100644 --- a/fs/ecryptfs/miscdev.c +++ b/fs/ecryptfs/miscdev.c | |||
@@ -49,7 +49,10 @@ ecryptfs_miscdev_poll(struct file *file, poll_table *pt) | |||
49 | mutex_lock(&ecryptfs_daemon_hash_mux); | 49 | mutex_lock(&ecryptfs_daemon_hash_mux); |
50 | /* TODO: Just use file->private_data? */ | 50 | /* TODO: Just use file->private_data? */ |
51 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); | 51 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); |
52 | BUG_ON(rc || !daemon); | 52 | if (rc || !daemon) { |
53 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
54 | return -EINVAL; | ||
55 | } | ||
53 | mutex_lock(&daemon->mux); | 56 | mutex_lock(&daemon->mux); |
54 | mutex_unlock(&ecryptfs_daemon_hash_mux); | 57 | mutex_unlock(&ecryptfs_daemon_hash_mux); |
55 | if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { | 58 | if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { |
@@ -122,6 +125,7 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file) | |||
122 | goto out_unlock_daemon; | 125 | goto out_unlock_daemon; |
123 | } | 126 | } |
124 | daemon->flags |= ECRYPTFS_DAEMON_MISCDEV_OPEN; | 127 | daemon->flags |= ECRYPTFS_DAEMON_MISCDEV_OPEN; |
128 | file->private_data = daemon; | ||
125 | atomic_inc(&ecryptfs_num_miscdev_opens); | 129 | atomic_inc(&ecryptfs_num_miscdev_opens); |
126 | out_unlock_daemon: | 130 | out_unlock_daemon: |
127 | mutex_unlock(&daemon->mux); | 131 | mutex_unlock(&daemon->mux); |
@@ -152,9 +156,9 @@ ecryptfs_miscdev_release(struct inode *inode, struct file *file) | |||
152 | 156 | ||
153 | mutex_lock(&ecryptfs_daemon_hash_mux); | 157 | mutex_lock(&ecryptfs_daemon_hash_mux); |
154 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); | 158 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); |
155 | BUG_ON(rc || !daemon); | 159 | if (rc || !daemon) |
160 | daemon = file->private_data; | ||
156 | mutex_lock(&daemon->mux); | 161 | mutex_lock(&daemon->mux); |
157 | BUG_ON(daemon->pid != task_pid(current)); | ||
158 | BUG_ON(!(daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN)); | 162 | BUG_ON(!(daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN)); |
159 | daemon->flags &= ~ECRYPTFS_DAEMON_MISCDEV_OPEN; | 163 | daemon->flags &= ~ECRYPTFS_DAEMON_MISCDEV_OPEN; |
160 | atomic_dec(&ecryptfs_num_miscdev_opens); | 164 | atomic_dec(&ecryptfs_num_miscdev_opens); |
@@ -191,31 +195,32 @@ int ecryptfs_send_miscdev(char *data, size_t data_size, | |||
191 | struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type, | 195 | struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type, |
192 | u16 msg_flags, struct ecryptfs_daemon *daemon) | 196 | u16 msg_flags, struct ecryptfs_daemon *daemon) |
193 | { | 197 | { |
194 | int rc = 0; | 198 | struct ecryptfs_message *msg; |
195 | 199 | ||
196 | mutex_lock(&msg_ctx->mux); | 200 | msg = kmalloc((sizeof(*msg) + data_size), GFP_KERNEL); |
197 | msg_ctx->msg = kmalloc((sizeof(*msg_ctx->msg) + data_size), | 201 | if (!msg) { |
198 | GFP_KERNEL); | ||
199 | if (!msg_ctx->msg) { | ||
200 | rc = -ENOMEM; | ||
201 | printk(KERN_ERR "%s: Out of memory whilst attempting " | 202 | printk(KERN_ERR "%s: Out of memory whilst attempting " |
202 | "to kmalloc(%zd, GFP_KERNEL)\n", __func__, | 203 | "to kmalloc(%zd, GFP_KERNEL)\n", __func__, |
203 | (sizeof(*msg_ctx->msg) + data_size)); | 204 | (sizeof(*msg) + data_size)); |
204 | goto out_unlock; | 205 | return -ENOMEM; |
205 | } | 206 | } |
207 | |||
208 | mutex_lock(&msg_ctx->mux); | ||
209 | msg_ctx->msg = msg; | ||
206 | msg_ctx->msg->index = msg_ctx->index; | 210 | msg_ctx->msg->index = msg_ctx->index; |
207 | msg_ctx->msg->data_len = data_size; | 211 | msg_ctx->msg->data_len = data_size; |
208 | msg_ctx->type = msg_type; | 212 | msg_ctx->type = msg_type; |
209 | memcpy(msg_ctx->msg->data, data, data_size); | 213 | memcpy(msg_ctx->msg->data, data, data_size); |
210 | msg_ctx->msg_size = (sizeof(*msg_ctx->msg) + data_size); | 214 | msg_ctx->msg_size = (sizeof(*msg_ctx->msg) + data_size); |
211 | mutex_lock(&daemon->mux); | ||
212 | list_add_tail(&msg_ctx->daemon_out_list, &daemon->msg_ctx_out_queue); | 215 | list_add_tail(&msg_ctx->daemon_out_list, &daemon->msg_ctx_out_queue); |
216 | mutex_unlock(&msg_ctx->mux); | ||
217 | |||
218 | mutex_lock(&daemon->mux); | ||
213 | daemon->num_queued_msg_ctx++; | 219 | daemon->num_queued_msg_ctx++; |
214 | wake_up_interruptible(&daemon->wait); | 220 | wake_up_interruptible(&daemon->wait); |
215 | mutex_unlock(&daemon->mux); | 221 | mutex_unlock(&daemon->mux); |
216 | out_unlock: | 222 | |
217 | mutex_unlock(&msg_ctx->mux); | 223 | return 0; |
218 | return rc; | ||
219 | } | 224 | } |
220 | 225 | ||
221 | /* | 226 | /* |
@@ -269,8 +274,16 @@ ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count, | |||
269 | mutex_lock(&ecryptfs_daemon_hash_mux); | 274 | mutex_lock(&ecryptfs_daemon_hash_mux); |
270 | /* TODO: Just use file->private_data? */ | 275 | /* TODO: Just use file->private_data? */ |
271 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); | 276 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); |
272 | BUG_ON(rc || !daemon); | 277 | if (rc || !daemon) { |
278 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
279 | return -EINVAL; | ||
280 | } | ||
273 | mutex_lock(&daemon->mux); | 281 | mutex_lock(&daemon->mux); |
282 | if (task_pid(current) != daemon->pid) { | ||
283 | mutex_unlock(&daemon->mux); | ||
284 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
285 | return -EPERM; | ||
286 | } | ||
274 | if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { | 287 | if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { |
275 | rc = 0; | 288 | rc = 0; |
276 | mutex_unlock(&ecryptfs_daemon_hash_mux); | 289 | mutex_unlock(&ecryptfs_daemon_hash_mux); |
@@ -307,9 +320,6 @@ check_list: | |||
307 | * message from the queue; try again */ | 320 | * message from the queue; try again */ |
308 | goto check_list; | 321 | goto check_list; |
309 | } | 322 | } |
310 | BUG_ON(euid != daemon->euid); | ||
311 | BUG_ON(current_user_ns() != daemon->user_ns); | ||
312 | BUG_ON(task_pid(current) != daemon->pid); | ||
313 | msg_ctx = list_first_entry(&daemon->msg_ctx_out_queue, | 323 | msg_ctx = list_first_entry(&daemon->msg_ctx_out_queue, |
314 | struct ecryptfs_msg_ctx, daemon_out_list); | 324 | struct ecryptfs_msg_ctx, daemon_out_list); |
315 | BUG_ON(!msg_ctx); | 325 | BUG_ON(!msg_ctx); |
diff --git a/fs/efs/efs.h b/fs/efs/efs.h index d8305b582ab0..5528926ac7f6 100644 --- a/fs/efs/efs.h +++ b/fs/efs/efs.h | |||
@@ -129,7 +129,7 @@ extern struct inode *efs_iget(struct super_block *, unsigned long); | |||
129 | extern efs_block_t efs_map_block(struct inode *, efs_block_t); | 129 | extern efs_block_t efs_map_block(struct inode *, efs_block_t); |
130 | extern int efs_get_block(struct inode *, sector_t, struct buffer_head *, int); | 130 | extern int efs_get_block(struct inode *, sector_t, struct buffer_head *, int); |
131 | 131 | ||
132 | extern struct dentry *efs_lookup(struct inode *, struct dentry *, struct nameidata *); | 132 | extern struct dentry *efs_lookup(struct inode *, struct dentry *, unsigned int); |
133 | extern struct dentry *efs_fh_to_dentry(struct super_block *sb, struct fid *fid, | 133 | extern struct dentry *efs_fh_to_dentry(struct super_block *sb, struct fid *fid, |
134 | int fh_len, int fh_type); | 134 | int fh_len, int fh_type); |
135 | extern struct dentry *efs_fh_to_parent(struct super_block *sb, struct fid *fid, | 135 | extern struct dentry *efs_fh_to_parent(struct super_block *sb, struct fid *fid, |
diff --git a/fs/efs/namei.c b/fs/efs/namei.c index 832b10ded82f..96f66d213a19 100644 --- a/fs/efs/namei.c +++ b/fs/efs/namei.c | |||
@@ -58,7 +58,8 @@ static efs_ino_t efs_find_entry(struct inode *inode, const char *name, int len) | |||
58 | return(0); | 58 | return(0); |
59 | } | 59 | } |
60 | 60 | ||
61 | struct dentry *efs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { | 61 | struct dentry *efs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) |
62 | { | ||
62 | efs_ino_t inodenum; | 63 | efs_ino_t inodenum; |
63 | struct inode *inode = NULL; | 64 | struct inode *inode = NULL; |
64 | 65 | ||
diff --git a/fs/exofs/namei.c b/fs/exofs/namei.c index fc7161d6bf6b..4731fd991efe 100644 --- a/fs/exofs/namei.c +++ b/fs/exofs/namei.c | |||
@@ -46,7 +46,7 @@ static inline int exofs_add_nondir(struct dentry *dentry, struct inode *inode) | |||
46 | } | 46 | } |
47 | 47 | ||
48 | static struct dentry *exofs_lookup(struct inode *dir, struct dentry *dentry, | 48 | static struct dentry *exofs_lookup(struct inode *dir, struct dentry *dentry, |
49 | struct nameidata *nd) | 49 | unsigned int flags) |
50 | { | 50 | { |
51 | struct inode *inode; | 51 | struct inode *inode; |
52 | ino_t ino; | 52 | ino_t ino; |
@@ -60,7 +60,7 @@ static struct dentry *exofs_lookup(struct inode *dir, struct dentry *dentry, | |||
60 | } | 60 | } |
61 | 61 | ||
62 | static int exofs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 62 | static int exofs_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
63 | struct nameidata *nd) | 63 | bool excl) |
64 | { | 64 | { |
65 | struct inode *inode = exofs_new_inode(dir, mode); | 65 | struct inode *inode = exofs_new_inode(dir, mode); |
66 | int err = PTR_ERR(inode); | 66 | int err = PTR_ERR(inode); |
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c index b0201ca6e9c6..b42063cf1b2d 100644 --- a/fs/exportfs/expfs.c +++ b/fs/exportfs/expfs.c | |||
@@ -44,13 +44,14 @@ find_acceptable_alias(struct dentry *result, | |||
44 | { | 44 | { |
45 | struct dentry *dentry, *toput = NULL; | 45 | struct dentry *dentry, *toput = NULL; |
46 | struct inode *inode; | 46 | struct inode *inode; |
47 | struct hlist_node *p; | ||
47 | 48 | ||
48 | if (acceptable(context, result)) | 49 | if (acceptable(context, result)) |
49 | return result; | 50 | return result; |
50 | 51 | ||
51 | inode = result->d_inode; | 52 | inode = result->d_inode; |
52 | spin_lock(&inode->i_lock); | 53 | spin_lock(&inode->i_lock); |
53 | list_for_each_entry(dentry, &inode->i_dentry, d_alias) { | 54 | hlist_for_each_entry(dentry, p, &inode->i_dentry, d_alias) { |
54 | dget(dentry); | 55 | dget(dentry); |
55 | spin_unlock(&inode->i_lock); | 56 | spin_unlock(&inode->i_lock); |
56 | if (toput) | 57 | if (toput) |
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index f663a67d7bf0..9ba7de0e5903 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c | |||
@@ -55,7 +55,7 @@ static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode) | |||
55 | * Methods themselves. | 55 | * Methods themselves. |
56 | */ | 56 | */ |
57 | 57 | ||
58 | static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd) | 58 | static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry, unsigned int flags) |
59 | { | 59 | { |
60 | struct inode * inode; | 60 | struct inode * inode; |
61 | ino_t ino; | 61 | ino_t ino; |
@@ -94,7 +94,7 @@ struct dentry *ext2_get_parent(struct dentry *child) | |||
94 | * If the create succeeds, we fill in the inode information | 94 | * If the create succeeds, we fill in the inode information |
95 | * with d_instantiate(). | 95 | * with d_instantiate(). |
96 | */ | 96 | */ |
97 | static int ext2_create (struct inode * dir, struct dentry * dentry, umode_t mode, struct nameidata *nd) | 97 | static int ext2_create (struct inode * dir, struct dentry * dentry, umode_t mode, bool excl) |
98 | { | 98 | { |
99 | struct inode *inode; | 99 | struct inode *inode; |
100 | 100 | ||
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index eeb63dfc5d20..85286dbe2753 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c | |||
@@ -1011,7 +1011,7 @@ errout: | |||
1011 | return NULL; | 1011 | return NULL; |
1012 | } | 1012 | } |
1013 | 1013 | ||
1014 | static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd) | 1014 | static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry, unsigned int flags) |
1015 | { | 1015 | { |
1016 | struct inode * inode; | 1016 | struct inode * inode; |
1017 | struct ext3_dir_entry_2 * de; | 1017 | struct ext3_dir_entry_2 * de; |
@@ -1690,7 +1690,7 @@ static int ext3_add_nondir(handle_t *handle, | |||
1690 | * with d_instantiate(). | 1690 | * with d_instantiate(). |
1691 | */ | 1691 | */ |
1692 | static int ext3_create (struct inode * dir, struct dentry * dentry, umode_t mode, | 1692 | static int ext3_create (struct inode * dir, struct dentry * dentry, umode_t mode, |
1693 | struct nameidata *nd) | 1693 | bool excl) |
1694 | { | 1694 | { |
1695 | handle_t *handle; | 1695 | handle_t *handle; |
1696 | struct inode * inode; | 1696 | struct inode * inode; |
diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c index bb6c7d811313..2a1dcea4f12e 100644 --- a/fs/ext4/fsync.c +++ b/fs/ext4/fsync.c | |||
@@ -135,14 +135,7 @@ static int ext4_sync_parent(struct inode *inode) | |||
135 | inode = igrab(inode); | 135 | inode = igrab(inode); |
136 | while (ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY)) { | 136 | while (ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY)) { |
137 | ext4_clear_inode_state(inode, EXT4_STATE_NEWENTRY); | 137 | ext4_clear_inode_state(inode, EXT4_STATE_NEWENTRY); |
138 | dentry = NULL; | 138 | dentry = d_find_any_alias(inode); |
139 | spin_lock(&inode->i_lock); | ||
140 | if (!list_empty(&inode->i_dentry)) { | ||
141 | dentry = list_first_entry(&inode->i_dentry, | ||
142 | struct dentry, d_alias); | ||
143 | dget(dentry); | ||
144 | } | ||
145 | spin_unlock(&inode->i_lock); | ||
146 | if (!dentry) | 139 | if (!dentry) |
147 | break; | 140 | break; |
148 | next = igrab(dentry->d_parent->d_inode); | 141 | next = igrab(dentry->d_parent->d_inode); |
@@ -232,7 +225,7 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync) | |||
232 | 225 | ||
233 | if (!journal) { | 226 | if (!journal) { |
234 | ret = __sync_inode(inode, datasync); | 227 | ret = __sync_inode(inode, datasync); |
235 | if (!ret && !list_empty(&inode->i_dentry)) | 228 | if (!ret && !hlist_empty(&inode->i_dentry)) |
236 | ret = ext4_sync_parent(inode); | 229 | ret = ext4_sync_parent(inode); |
237 | goto out; | 230 | goto out; |
238 | } | 231 | } |
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 5845cd97bf8b..eca3e48a62f8 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -1312,7 +1312,7 @@ errout: | |||
1312 | return NULL; | 1312 | return NULL; |
1313 | } | 1313 | } |
1314 | 1314 | ||
1315 | static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | 1315 | static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) |
1316 | { | 1316 | { |
1317 | struct inode *inode; | 1317 | struct inode *inode; |
1318 | struct ext4_dir_entry_2 *de; | 1318 | struct ext4_dir_entry_2 *de; |
@@ -2091,7 +2091,7 @@ static int ext4_add_nondir(handle_t *handle, | |||
2091 | * with d_instantiate(). | 2091 | * with d_instantiate(). |
2092 | */ | 2092 | */ |
2093 | static int ext4_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 2093 | static int ext4_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
2094 | struct nameidata *nd) | 2094 | bool excl) |
2095 | { | 2095 | { |
2096 | handle_t *handle; | 2096 | handle_t *handle; |
2097 | struct inode *inode; | 2097 | struct inode *inode; |
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index a3d81ebf6d86..0038b32cb362 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
@@ -738,22 +738,21 @@ static int | |||
738 | fat_encode_fh(struct inode *inode, __u32 *fh, int *lenp, struct inode *parent) | 738 | fat_encode_fh(struct inode *inode, __u32 *fh, int *lenp, struct inode *parent) |
739 | { | 739 | { |
740 | int len = *lenp; | 740 | int len = *lenp; |
741 | u32 ipos_h, ipos_m, ipos_l; | 741 | struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); |
742 | loff_t i_pos; | ||
742 | 743 | ||
743 | if (len < 5) { | 744 | if (len < 5) { |
744 | *lenp = 5; | 745 | *lenp = 5; |
745 | return 255; /* no room */ | 746 | return 255; /* no room */ |
746 | } | 747 | } |
747 | 748 | ||
748 | ipos_h = MSDOS_I(inode)->i_pos >> 8; | 749 | i_pos = fat_i_pos_read(sbi, inode); |
749 | ipos_m = (MSDOS_I(inode)->i_pos & 0xf0) << 24; | ||
750 | ipos_l = (MSDOS_I(inode)->i_pos & 0x0f) << 28; | ||
751 | *lenp = 5; | 750 | *lenp = 5; |
752 | fh[0] = inode->i_ino; | 751 | fh[0] = inode->i_ino; |
753 | fh[1] = inode->i_generation; | 752 | fh[1] = inode->i_generation; |
754 | fh[2] = ipos_h; | 753 | fh[2] = i_pos >> 8; |
755 | fh[3] = ipos_m | MSDOS_I(inode)->i_logstart; | 754 | fh[3] = ((i_pos & 0xf0) << 24) | MSDOS_I(inode)->i_logstart; |
756 | fh[4] = ipos_l; | 755 | fh[4] = (i_pos & 0x0f) << 28; |
757 | if (parent) | 756 | if (parent) |
758 | fh[4] |= MSDOS_I(parent)->i_logstart; | 757 | fh[4] |= MSDOS_I(parent)->i_logstart; |
759 | return 3; | 758 | return 3; |
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c index c5938c9084b9..70d993a93805 100644 --- a/fs/fat/namei_msdos.c +++ b/fs/fat/namei_msdos.c | |||
@@ -201,7 +201,7 @@ static const struct dentry_operations msdos_dentry_operations = { | |||
201 | 201 | ||
202 | /***** Get inode using directory and name */ | 202 | /***** Get inode using directory and name */ |
203 | static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry, | 203 | static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry, |
204 | struct nameidata *nd) | 204 | unsigned int flags) |
205 | { | 205 | { |
206 | struct super_block *sb = dir->i_sb; | 206 | struct super_block *sb = dir->i_sb; |
207 | struct fat_slot_info sinfo; | 207 | struct fat_slot_info sinfo; |
@@ -265,7 +265,7 @@ static int msdos_add_entry(struct inode *dir, const unsigned char *name, | |||
265 | 265 | ||
266 | /***** Create a file */ | 266 | /***** Create a file */ |
267 | static int msdos_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 267 | static int msdos_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
268 | struct nameidata *nd) | 268 | bool excl) |
269 | { | 269 | { |
270 | struct super_block *sb = dir->i_sb; | 270 | struct super_block *sb = dir->i_sb; |
271 | struct inode *inode = NULL; | 271 | struct inode *inode = NULL; |
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index 98ae804f5273..6cc480652433 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c | |||
@@ -41,9 +41,9 @@ static int vfat_revalidate_shortname(struct dentry *dentry) | |||
41 | return ret; | 41 | return ret; |
42 | } | 42 | } |
43 | 43 | ||
44 | static int vfat_revalidate(struct dentry *dentry, struct nameidata *nd) | 44 | static int vfat_revalidate(struct dentry *dentry, unsigned int flags) |
45 | { | 45 | { |
46 | if (nd && nd->flags & LOOKUP_RCU) | 46 | if (flags & LOOKUP_RCU) |
47 | return -ECHILD; | 47 | return -ECHILD; |
48 | 48 | ||
49 | /* This is not negative dentry. Always valid. */ | 49 | /* This is not negative dentry. Always valid. */ |
@@ -52,9 +52,9 @@ static int vfat_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
52 | return vfat_revalidate_shortname(dentry); | 52 | return vfat_revalidate_shortname(dentry); |
53 | } | 53 | } |
54 | 54 | ||
55 | static int vfat_revalidate_ci(struct dentry *dentry, struct nameidata *nd) | 55 | static int vfat_revalidate_ci(struct dentry *dentry, unsigned int flags) |
56 | { | 56 | { |
57 | if (nd && nd->flags & LOOKUP_RCU) | 57 | if (flags & LOOKUP_RCU) |
58 | return -ECHILD; | 58 | return -ECHILD; |
59 | 59 | ||
60 | /* | 60 | /* |
@@ -74,7 +74,7 @@ static int vfat_revalidate_ci(struct dentry *dentry, struct nameidata *nd) | |||
74 | * This may be nfsd (or something), anyway, we can't see the | 74 | * This may be nfsd (or something), anyway, we can't see the |
75 | * intent of this. So, since this can be for creation, drop it. | 75 | * intent of this. So, since this can be for creation, drop it. |
76 | */ | 76 | */ |
77 | if (!nd) | 77 | if (!flags) |
78 | return 0; | 78 | return 0; |
79 | 79 | ||
80 | /* | 80 | /* |
@@ -82,7 +82,7 @@ static int vfat_revalidate_ci(struct dentry *dentry, struct nameidata *nd) | |||
82 | * case sensitive name which is specified by user if this is | 82 | * case sensitive name which is specified by user if this is |
83 | * for creation. | 83 | * for creation. |
84 | */ | 84 | */ |
85 | if (nd->flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET)) | 85 | if (flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET)) |
86 | return 0; | 86 | return 0; |
87 | 87 | ||
88 | return vfat_revalidate_shortname(dentry); | 88 | return vfat_revalidate_shortname(dentry); |
@@ -714,7 +714,7 @@ static int vfat_d_anon_disconn(struct dentry *dentry) | |||
714 | } | 714 | } |
715 | 715 | ||
716 | static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry, | 716 | static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry, |
717 | struct nameidata *nd) | 717 | unsigned int flags) |
718 | { | 718 | { |
719 | struct super_block *sb = dir->i_sb; | 719 | struct super_block *sb = dir->i_sb; |
720 | struct fat_slot_info sinfo; | 720 | struct fat_slot_info sinfo; |
@@ -772,7 +772,7 @@ error: | |||
772 | } | 772 | } |
773 | 773 | ||
774 | static int vfat_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 774 | static int vfat_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
775 | struct nameidata *nd) | 775 | bool excl) |
776 | { | 776 | { |
777 | struct super_block *sb = dir->i_sb; | 777 | struct super_block *sb = dir->i_sb; |
778 | struct inode *inode; | 778 | struct inode *inode; |
diff --git a/fs/file_table.c b/fs/file_table.c index a305d9e2d1b2..9ace2781931e 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
@@ -483,10 +483,8 @@ void mark_files_ro(struct super_block *sb) | |||
483 | { | 483 | { |
484 | struct file *f; | 484 | struct file *f; |
485 | 485 | ||
486 | retry: | ||
487 | lg_global_lock(&files_lglock); | 486 | lg_global_lock(&files_lglock); |
488 | do_file_list_for_each_entry(sb, f) { | 487 | do_file_list_for_each_entry(sb, f) { |
489 | struct vfsmount *mnt; | ||
490 | if (!S_ISREG(f->f_path.dentry->d_inode->i_mode)) | 488 | if (!S_ISREG(f->f_path.dentry->d_inode->i_mode)) |
491 | continue; | 489 | continue; |
492 | if (!file_count(f)) | 490 | if (!file_count(f)) |
@@ -499,12 +497,7 @@ retry: | |||
499 | if (file_check_writeable(f) != 0) | 497 | if (file_check_writeable(f) != 0) |
500 | continue; | 498 | continue; |
501 | file_release_write(f); | 499 | file_release_write(f); |
502 | mnt = mntget(f->f_path.mnt); | 500 | mnt_drop_write_file(f); |
503 | /* This can sleep, so we can't hold the spinlock. */ | ||
504 | lg_global_unlock(&files_lglock); | ||
505 | mnt_drop_write(mnt); | ||
506 | mntput(mnt); | ||
507 | goto retry; | ||
508 | } while_file_list_for_each_entry; | 501 | } while_file_list_for_each_entry; |
509 | lg_global_unlock(&files_lglock); | 502 | lg_global_unlock(&files_lglock); |
510 | } | 503 | } |
diff --git a/fs/freevxfs/vxfs_lookup.c b/fs/freevxfs/vxfs_lookup.c index 3360f1e678ad..bd447e88f208 100644 --- a/fs/freevxfs/vxfs_lookup.c +++ b/fs/freevxfs/vxfs_lookup.c | |||
@@ -48,7 +48,7 @@ | |||
48 | #define VXFS_BLOCK_PER_PAGE(sbp) ((PAGE_CACHE_SIZE / (sbp)->s_blocksize)) | 48 | #define VXFS_BLOCK_PER_PAGE(sbp) ((PAGE_CACHE_SIZE / (sbp)->s_blocksize)) |
49 | 49 | ||
50 | 50 | ||
51 | static struct dentry * vxfs_lookup(struct inode *, struct dentry *, struct nameidata *); | 51 | static struct dentry * vxfs_lookup(struct inode *, struct dentry *, unsigned int); |
52 | static int vxfs_readdir(struct file *, void *, filldir_t); | 52 | static int vxfs_readdir(struct file *, void *, filldir_t); |
53 | 53 | ||
54 | const struct inode_operations vxfs_dir_inode_ops = { | 54 | const struct inode_operations vxfs_dir_inode_ops = { |
@@ -203,7 +203,7 @@ vxfs_inode_by_name(struct inode *dip, struct dentry *dp) | |||
203 | * in the return pointer. | 203 | * in the return pointer. |
204 | */ | 204 | */ |
205 | static struct dentry * | 205 | static struct dentry * |
206 | vxfs_lookup(struct inode *dip, struct dentry *dp, struct nameidata *nd) | 206 | vxfs_lookup(struct inode *dip, struct dentry *dp, unsigned int flags) |
207 | { | 207 | { |
208 | struct inode *ip = NULL; | 208 | struct inode *ip = NULL; |
209 | ino_t ino; | 209 | ino_t ino; |
diff --git a/fs/fs_struct.c b/fs/fs_struct.c index e159e682ad4c..5df4775fea03 100644 --- a/fs/fs_struct.c +++ b/fs/fs_struct.c | |||
@@ -6,18 +6,6 @@ | |||
6 | #include <linux/fs_struct.h> | 6 | #include <linux/fs_struct.h> |
7 | #include "internal.h" | 7 | #include "internal.h" |
8 | 8 | ||
9 | static inline void path_get_longterm(struct path *path) | ||
10 | { | ||
11 | path_get(path); | ||
12 | mnt_make_longterm(path->mnt); | ||
13 | } | ||
14 | |||
15 | static inline void path_put_longterm(struct path *path) | ||
16 | { | ||
17 | mnt_make_shortterm(path->mnt); | ||
18 | path_put(path); | ||
19 | } | ||
20 | |||
21 | /* | 9 | /* |
22 | * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values. | 10 | * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values. |
23 | * It can block. | 11 | * It can block. |
@@ -26,7 +14,7 @@ void set_fs_root(struct fs_struct *fs, struct path *path) | |||
26 | { | 14 | { |
27 | struct path old_root; | 15 | struct path old_root; |
28 | 16 | ||
29 | path_get_longterm(path); | 17 | path_get(path); |
30 | spin_lock(&fs->lock); | 18 | spin_lock(&fs->lock); |
31 | write_seqcount_begin(&fs->seq); | 19 | write_seqcount_begin(&fs->seq); |
32 | old_root = fs->root; | 20 | old_root = fs->root; |
@@ -34,7 +22,7 @@ void set_fs_root(struct fs_struct *fs, struct path *path) | |||
34 | write_seqcount_end(&fs->seq); | 22 | write_seqcount_end(&fs->seq); |
35 | spin_unlock(&fs->lock); | 23 | spin_unlock(&fs->lock); |
36 | if (old_root.dentry) | 24 | if (old_root.dentry) |
37 | path_put_longterm(&old_root); | 25 | path_put(&old_root); |
38 | } | 26 | } |
39 | 27 | ||
40 | /* | 28 | /* |
@@ -45,7 +33,7 @@ void set_fs_pwd(struct fs_struct *fs, struct path *path) | |||
45 | { | 33 | { |
46 | struct path old_pwd; | 34 | struct path old_pwd; |
47 | 35 | ||
48 | path_get_longterm(path); | 36 | path_get(path); |
49 | spin_lock(&fs->lock); | 37 | spin_lock(&fs->lock); |
50 | write_seqcount_begin(&fs->seq); | 38 | write_seqcount_begin(&fs->seq); |
51 | old_pwd = fs->pwd; | 39 | old_pwd = fs->pwd; |
@@ -54,7 +42,7 @@ void set_fs_pwd(struct fs_struct *fs, struct path *path) | |||
54 | spin_unlock(&fs->lock); | 42 | spin_unlock(&fs->lock); |
55 | 43 | ||
56 | if (old_pwd.dentry) | 44 | if (old_pwd.dentry) |
57 | path_put_longterm(&old_pwd); | 45 | path_put(&old_pwd); |
58 | } | 46 | } |
59 | 47 | ||
60 | static inline int replace_path(struct path *p, const struct path *old, const struct path *new) | 48 | static inline int replace_path(struct path *p, const struct path *old, const struct path *new) |
@@ -84,7 +72,7 @@ void chroot_fs_refs(struct path *old_root, struct path *new_root) | |||
84 | write_seqcount_end(&fs->seq); | 72 | write_seqcount_end(&fs->seq); |
85 | while (hits--) { | 73 | while (hits--) { |
86 | count++; | 74 | count++; |
87 | path_get_longterm(new_root); | 75 | path_get(new_root); |
88 | } | 76 | } |
89 | spin_unlock(&fs->lock); | 77 | spin_unlock(&fs->lock); |
90 | } | 78 | } |
@@ -92,13 +80,13 @@ void chroot_fs_refs(struct path *old_root, struct path *new_root) | |||
92 | } while_each_thread(g, p); | 80 | } while_each_thread(g, p); |
93 | read_unlock(&tasklist_lock); | 81 | read_unlock(&tasklist_lock); |
94 | while (count--) | 82 | while (count--) |
95 | path_put_longterm(old_root); | 83 | path_put(old_root); |
96 | } | 84 | } |
97 | 85 | ||
98 | void free_fs_struct(struct fs_struct *fs) | 86 | void free_fs_struct(struct fs_struct *fs) |
99 | { | 87 | { |
100 | path_put_longterm(&fs->root); | 88 | path_put(&fs->root); |
101 | path_put_longterm(&fs->pwd); | 89 | path_put(&fs->pwd); |
102 | kmem_cache_free(fs_cachep, fs); | 90 | kmem_cache_free(fs_cachep, fs); |
103 | } | 91 | } |
104 | 92 | ||
@@ -132,9 +120,9 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old) | |||
132 | 120 | ||
133 | spin_lock(&old->lock); | 121 | spin_lock(&old->lock); |
134 | fs->root = old->root; | 122 | fs->root = old->root; |
135 | path_get_longterm(&fs->root); | 123 | path_get(&fs->root); |
136 | fs->pwd = old->pwd; | 124 | fs->pwd = old->pwd; |
137 | path_get_longterm(&fs->pwd); | 125 | path_get(&fs->pwd); |
138 | spin_unlock(&old->lock); | 126 | spin_unlock(&old->lock); |
139 | } | 127 | } |
140 | return fs; | 128 | return fs; |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 334e0b18a014..8964cf3999b2 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -154,7 +154,7 @@ u64 fuse_get_attr_version(struct fuse_conn *fc) | |||
154 | * the lookup once more. If the lookup results in the same inode, | 154 | * the lookup once more. If the lookup results in the same inode, |
155 | * then refresh the attributes, timeouts and mark the dentry valid. | 155 | * then refresh the attributes, timeouts and mark the dentry valid. |
156 | */ | 156 | */ |
157 | static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) | 157 | static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags) |
158 | { | 158 | { |
159 | struct inode *inode; | 159 | struct inode *inode; |
160 | 160 | ||
@@ -174,7 +174,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) | |||
174 | if (!inode) | 174 | if (!inode) |
175 | return 0; | 175 | return 0; |
176 | 176 | ||
177 | if (nd && (nd->flags & LOOKUP_RCU)) | 177 | if (flags & LOOKUP_RCU) |
178 | return -ECHILD; | 178 | return -ECHILD; |
179 | 179 | ||
180 | fc = get_fuse_conn(inode); | 180 | fc = get_fuse_conn(inode); |
@@ -249,7 +249,7 @@ static struct dentry *fuse_d_add_directory(struct dentry *entry, | |||
249 | /* This tries to shrink the subtree below alias */ | 249 | /* This tries to shrink the subtree below alias */ |
250 | fuse_invalidate_entry(alias); | 250 | fuse_invalidate_entry(alias); |
251 | dput(alias); | 251 | dput(alias); |
252 | if (!list_empty(&inode->i_dentry)) | 252 | if (!hlist_empty(&inode->i_dentry)) |
253 | return ERR_PTR(-EBUSY); | 253 | return ERR_PTR(-EBUSY); |
254 | } else { | 254 | } else { |
255 | dput(alias); | 255 | dput(alias); |
@@ -316,7 +316,7 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name, | |||
316 | } | 316 | } |
317 | 317 | ||
318 | static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, | 318 | static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, |
319 | struct nameidata *nd) | 319 | unsigned int flags) |
320 | { | 320 | { |
321 | int err; | 321 | int err; |
322 | struct fuse_entry_out outarg; | 322 | struct fuse_entry_out outarg; |
@@ -370,7 +370,8 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, | |||
370 | * 'mknod' + 'open' requests. | 370 | * 'mknod' + 'open' requests. |
371 | */ | 371 | */ |
372 | static int fuse_create_open(struct inode *dir, struct dentry *entry, | 372 | static int fuse_create_open(struct inode *dir, struct dentry *entry, |
373 | umode_t mode, struct nameidata *nd) | 373 | struct file *file, unsigned flags, |
374 | umode_t mode, int *opened) | ||
374 | { | 375 | { |
375 | int err; | 376 | int err; |
376 | struct inode *inode; | 377 | struct inode *inode; |
@@ -381,15 +382,11 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, | |||
381 | struct fuse_open_out outopen; | 382 | struct fuse_open_out outopen; |
382 | struct fuse_entry_out outentry; | 383 | struct fuse_entry_out outentry; |
383 | struct fuse_file *ff; | 384 | struct fuse_file *ff; |
384 | struct file *file; | ||
385 | int flags = nd->intent.open.flags; | ||
386 | |||
387 | if (fc->no_create) | ||
388 | return -ENOSYS; | ||
389 | 385 | ||
390 | forget = fuse_alloc_forget(); | 386 | forget = fuse_alloc_forget(); |
387 | err = -ENOMEM; | ||
391 | if (!forget) | 388 | if (!forget) |
392 | return -ENOMEM; | 389 | goto out_err; |
393 | 390 | ||
394 | req = fuse_get_req(fc); | 391 | req = fuse_get_req(fc); |
395 | err = PTR_ERR(req); | 392 | err = PTR_ERR(req); |
@@ -428,11 +425,8 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, | |||
428 | req->out.args[1].value = &outopen; | 425 | req->out.args[1].value = &outopen; |
429 | fuse_request_send(fc, req); | 426 | fuse_request_send(fc, req); |
430 | err = req->out.h.error; | 427 | err = req->out.h.error; |
431 | if (err) { | 428 | if (err) |
432 | if (err == -ENOSYS) | ||
433 | fc->no_create = 1; | ||
434 | goto out_free_ff; | 429 | goto out_free_ff; |
435 | } | ||
436 | 430 | ||
437 | err = -EIO; | 431 | err = -EIO; |
438 | if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid)) | 432 | if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid)) |
@@ -448,28 +442,74 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, | |||
448 | flags &= ~(O_CREAT | O_EXCL | O_TRUNC); | 442 | flags &= ~(O_CREAT | O_EXCL | O_TRUNC); |
449 | fuse_sync_release(ff, flags); | 443 | fuse_sync_release(ff, flags); |
450 | fuse_queue_forget(fc, forget, outentry.nodeid, 1); | 444 | fuse_queue_forget(fc, forget, outentry.nodeid, 1); |
451 | return -ENOMEM; | 445 | err = -ENOMEM; |
446 | goto out_err; | ||
452 | } | 447 | } |
453 | kfree(forget); | 448 | kfree(forget); |
454 | d_instantiate(entry, inode); | 449 | d_instantiate(entry, inode); |
455 | fuse_change_entry_timeout(entry, &outentry); | 450 | fuse_change_entry_timeout(entry, &outentry); |
456 | fuse_invalidate_attr(dir); | 451 | fuse_invalidate_attr(dir); |
457 | file = lookup_instantiate_filp(nd, entry, generic_file_open); | 452 | err = finish_open(file, entry, generic_file_open, opened); |
458 | if (IS_ERR(file)) { | 453 | if (err) { |
459 | fuse_sync_release(ff, flags); | 454 | fuse_sync_release(ff, flags); |
460 | return PTR_ERR(file); | 455 | } else { |
456 | file->private_data = fuse_file_get(ff); | ||
457 | fuse_finish_open(inode, file); | ||
461 | } | 458 | } |
462 | file->private_data = fuse_file_get(ff); | 459 | return err; |
463 | fuse_finish_open(inode, file); | ||
464 | return 0; | ||
465 | 460 | ||
466 | out_free_ff: | 461 | out_free_ff: |
467 | fuse_file_free(ff); | 462 | fuse_file_free(ff); |
468 | out_put_request: | 463 | out_put_request: |
469 | fuse_put_request(fc, req); | 464 | fuse_put_request(fc, req); |
470 | out_put_forget_req: | 465 | out_put_forget_req: |
471 | kfree(forget); | 466 | kfree(forget); |
467 | out_err: | ||
468 | return err; | ||
469 | } | ||
470 | |||
471 | static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t); | ||
472 | static int fuse_atomic_open(struct inode *dir, struct dentry *entry, | ||
473 | struct file *file, unsigned flags, | ||
474 | umode_t mode, int *opened) | ||
475 | { | ||
476 | int err; | ||
477 | struct fuse_conn *fc = get_fuse_conn(dir); | ||
478 | struct dentry *res = NULL; | ||
479 | |||
480 | if (d_unhashed(entry)) { | ||
481 | res = fuse_lookup(dir, entry, 0); | ||
482 | if (IS_ERR(res)) | ||
483 | return PTR_ERR(res); | ||
484 | |||
485 | if (res) | ||
486 | entry = res; | ||
487 | } | ||
488 | |||
489 | if (!(flags & O_CREAT) || entry->d_inode) | ||
490 | goto no_open; | ||
491 | |||
492 | /* Only creates */ | ||
493 | *opened |= FILE_CREATED; | ||
494 | |||
495 | if (fc->no_create) | ||
496 | goto mknod; | ||
497 | |||
498 | err = fuse_create_open(dir, entry, file, flags, mode, opened); | ||
499 | if (err == -ENOSYS) { | ||
500 | fc->no_create = 1; | ||
501 | goto mknod; | ||
502 | } | ||
503 | out_dput: | ||
504 | dput(res); | ||
472 | return err; | 505 | return err; |
506 | |||
507 | mknod: | ||
508 | err = fuse_mknod(dir, entry, mode, 0); | ||
509 | if (err) | ||
510 | goto out_dput; | ||
511 | no_open: | ||
512 | return finish_no_open(file, res); | ||
473 | } | 513 | } |
474 | 514 | ||
475 | /* | 515 | /* |
@@ -571,14 +611,8 @@ static int fuse_mknod(struct inode *dir, struct dentry *entry, umode_t mode, | |||
571 | } | 611 | } |
572 | 612 | ||
573 | static int fuse_create(struct inode *dir, struct dentry *entry, umode_t mode, | 613 | static int fuse_create(struct inode *dir, struct dentry *entry, umode_t mode, |
574 | struct nameidata *nd) | 614 | bool excl) |
575 | { | 615 | { |
576 | if (nd) { | ||
577 | int err = fuse_create_open(dir, entry, mode, nd); | ||
578 | if (err != -ENOSYS) | ||
579 | return err; | ||
580 | /* Fall back on mknod */ | ||
581 | } | ||
582 | return fuse_mknod(dir, entry, mode, 0); | 616 | return fuse_mknod(dir, entry, mode, 0); |
583 | } | 617 | } |
584 | 618 | ||
@@ -1646,6 +1680,7 @@ static const struct inode_operations fuse_dir_inode_operations = { | |||
1646 | .link = fuse_link, | 1680 | .link = fuse_link, |
1647 | .setattr = fuse_setattr, | 1681 | .setattr = fuse_setattr, |
1648 | .create = fuse_create, | 1682 | .create = fuse_create, |
1683 | .atomic_open = fuse_atomic_open, | ||
1649 | .mknod = fuse_mknod, | 1684 | .mknod = fuse_mknod, |
1650 | .permission = fuse_permission, | 1685 | .permission = fuse_permission, |
1651 | .getattr = fuse_getattr, | 1686 | .getattr = fuse_getattr, |
diff --git a/fs/gfs2/dentry.c b/fs/gfs2/dentry.c index 0da8da2c991d..4fddb3c22d25 100644 --- a/fs/gfs2/dentry.c +++ b/fs/gfs2/dentry.c | |||
@@ -25,7 +25,7 @@ | |||
25 | /** | 25 | /** |
26 | * gfs2_drevalidate - Check directory lookup consistency | 26 | * gfs2_drevalidate - Check directory lookup consistency |
27 | * @dentry: the mapping to check | 27 | * @dentry: the mapping to check |
28 | * @nd: | 28 | * @flags: lookup flags |
29 | * | 29 | * |
30 | * Check to make sure the lookup necessary to arrive at this inode from its | 30 | * Check to make sure the lookup necessary to arrive at this inode from its |
31 | * parent is still good. | 31 | * parent is still good. |
@@ -33,7 +33,7 @@ | |||
33 | * Returns: 1 if the dentry is ok, 0 if it isn't | 33 | * Returns: 1 if the dentry is ok, 0 if it isn't |
34 | */ | 34 | */ |
35 | 35 | ||
36 | static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd) | 36 | static int gfs2_drevalidate(struct dentry *dentry, unsigned int flags) |
37 | { | 37 | { |
38 | struct dentry *parent; | 38 | struct dentry *parent; |
39 | struct gfs2_sbd *sdp; | 39 | struct gfs2_sbd *sdp; |
@@ -44,7 +44,7 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd) | |||
44 | int error; | 44 | int error; |
45 | int had_lock = 0; | 45 | int had_lock = 0; |
46 | 46 | ||
47 | if (nd && nd->flags & LOOKUP_RCU) | 47 | if (flags & LOOKUP_RCU) |
48 | return -ECHILD; | 48 | return -ECHILD; |
49 | 49 | ||
50 | parent = dget_parent(dentry); | 50 | parent = dget_parent(dentry); |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index a9ba2444e077..867674785fcf 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -755,11 +755,8 @@ fail: | |||
755 | */ | 755 | */ |
756 | 756 | ||
757 | static int gfs2_create(struct inode *dir, struct dentry *dentry, | 757 | static int gfs2_create(struct inode *dir, struct dentry *dentry, |
758 | umode_t mode, struct nameidata *nd) | 758 | umode_t mode, bool excl) |
759 | { | 759 | { |
760 | int excl = 0; | ||
761 | if (nd && (nd->flags & LOOKUP_EXCL)) | ||
762 | excl = 1; | ||
763 | return gfs2_create_inode(dir, dentry, S_IFREG | mode, 0, NULL, 0, excl); | 760 | return gfs2_create_inode(dir, dentry, S_IFREG | mode, 0, NULL, 0, excl); |
764 | } | 761 | } |
765 | 762 | ||
@@ -775,7 +772,7 @@ static int gfs2_create(struct inode *dir, struct dentry *dentry, | |||
775 | */ | 772 | */ |
776 | 773 | ||
777 | static struct dentry *gfs2_lookup(struct inode *dir, struct dentry *dentry, | 774 | static struct dentry *gfs2_lookup(struct inode *dir, struct dentry *dentry, |
778 | struct nameidata *nd) | 775 | unsigned int flags) |
779 | { | 776 | { |
780 | struct inode *inode = gfs2_lookupi(dir, &dentry->d_name, 0); | 777 | struct inode *inode = gfs2_lookupi(dir, &dentry->d_name, 0); |
781 | if (inode && !IS_ERR(inode)) { | 778 | if (inode && !IS_ERR(inode)) { |
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index b8c250fc4922..6c906078f657 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c | |||
@@ -1286,7 +1286,7 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags, | |||
1286 | error = -EBUSY; | 1286 | error = -EBUSY; |
1287 | goto error_bdev; | 1287 | goto error_bdev; |
1288 | } | 1288 | } |
1289 | s = sget(fs_type, test_gfs2_super, set_gfs2_super, bdev); | 1289 | s = sget(fs_type, test_gfs2_super, set_gfs2_super, flags, bdev); |
1290 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | 1290 | mutex_unlock(&bdev->bd_fsfreeze_mutex); |
1291 | error = PTR_ERR(s); | 1291 | error = PTR_ERR(s); |
1292 | if (IS_ERR(s)) | 1292 | if (IS_ERR(s)) |
@@ -1316,7 +1316,6 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags, | |||
1316 | } else { | 1316 | } else { |
1317 | char b[BDEVNAME_SIZE]; | 1317 | char b[BDEVNAME_SIZE]; |
1318 | 1318 | ||
1319 | s->s_flags = flags; | ||
1320 | s->s_mode = mode; | 1319 | s->s_mode = mode; |
1321 | strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); | 1320 | strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); |
1322 | sb_set_blocksize(s, block_size(bdev)); | 1321 | sb_set_blocksize(s, block_size(bdev)); |
@@ -1360,7 +1359,7 @@ static struct dentry *gfs2_mount_meta(struct file_system_type *fs_type, | |||
1360 | dev_name, error); | 1359 | dev_name, error); |
1361 | return ERR_PTR(error); | 1360 | return ERR_PTR(error); |
1362 | } | 1361 | } |
1363 | s = sget(&gfs2_fs_type, test_gfs2_super, set_meta_super, | 1362 | s = sget(&gfs2_fs_type, test_gfs2_super, set_meta_super, flags, |
1364 | path.dentry->d_inode->i_sb->s_bdev); | 1363 | path.dentry->d_inode->i_sb->s_bdev); |
1365 | path_put(&path); | 1364 | path_put(&path); |
1366 | if (IS_ERR(s)) { | 1365 | if (IS_ERR(s)) { |
diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c index 62fc14ea4b73..422dde2ec0a1 100644 --- a/fs/hfs/dir.c +++ b/fs/hfs/dir.c | |||
@@ -18,7 +18,7 @@ | |||
18 | * hfs_lookup() | 18 | * hfs_lookup() |
19 | */ | 19 | */ |
20 | static struct dentry *hfs_lookup(struct inode *dir, struct dentry *dentry, | 20 | static struct dentry *hfs_lookup(struct inode *dir, struct dentry *dentry, |
21 | struct nameidata *nd) | 21 | unsigned int flags) |
22 | { | 22 | { |
23 | hfs_cat_rec rec; | 23 | hfs_cat_rec rec; |
24 | struct hfs_find_data fd; | 24 | struct hfs_find_data fd; |
@@ -187,7 +187,7 @@ static int hfs_dir_release(struct inode *inode, struct file *file) | |||
187 | * the directory and the name (and its length) of the new file. | 187 | * the directory and the name (and its length) of the new file. |
188 | */ | 188 | */ |
189 | static int hfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 189 | static int hfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
190 | struct nameidata *nd) | 190 | bool excl) |
191 | { | 191 | { |
192 | struct inode *inode; | 192 | struct inode *inode; |
193 | int res; | 193 | int res; |
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index 761ec06354b4..451c97281b83 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c | |||
@@ -489,7 +489,7 @@ out: | |||
489 | } | 489 | } |
490 | 490 | ||
491 | static struct dentry *hfs_file_lookup(struct inode *dir, struct dentry *dentry, | 491 | static struct dentry *hfs_file_lookup(struct inode *dir, struct dentry *dentry, |
492 | struct nameidata *nd) | 492 | unsigned int flags) |
493 | { | 493 | { |
494 | struct inode *inode = NULL; | 494 | struct inode *inode = NULL; |
495 | hfs_cat_rec rec; | 495 | hfs_cat_rec rec; |
diff --git a/fs/hfs/sysdep.c b/fs/hfs/sysdep.c index 19cf291eb91f..91b91fd3a901 100644 --- a/fs/hfs/sysdep.c +++ b/fs/hfs/sysdep.c | |||
@@ -13,12 +13,12 @@ | |||
13 | 13 | ||
14 | /* dentry case-handling: just lowercase everything */ | 14 | /* dentry case-handling: just lowercase everything */ |
15 | 15 | ||
16 | static int hfs_revalidate_dentry(struct dentry *dentry, struct nameidata *nd) | 16 | static int hfs_revalidate_dentry(struct dentry *dentry, unsigned int flags) |
17 | { | 17 | { |
18 | struct inode *inode; | 18 | struct inode *inode; |
19 | int diff; | 19 | int diff; |
20 | 20 | ||
21 | if (nd->flags & LOOKUP_RCU) | 21 | if (flags & LOOKUP_RCU) |
22 | return -ECHILD; | 22 | return -ECHILD; |
23 | 23 | ||
24 | inode = dentry->d_inode; | 24 | inode = dentry->d_inode; |
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index 26b53fb09f68..378ea0c43f19 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c | |||
@@ -25,7 +25,7 @@ static inline void hfsplus_instantiate(struct dentry *dentry, | |||
25 | 25 | ||
26 | /* Find the entry inside dir named dentry->d_name */ | 26 | /* Find the entry inside dir named dentry->d_name */ |
27 | static struct dentry *hfsplus_lookup(struct inode *dir, struct dentry *dentry, | 27 | static struct dentry *hfsplus_lookup(struct inode *dir, struct dentry *dentry, |
28 | struct nameidata *nd) | 28 | unsigned int flags) |
29 | { | 29 | { |
30 | struct inode *inode = NULL; | 30 | struct inode *inode = NULL; |
31 | struct hfs_find_data fd; | 31 | struct hfs_find_data fd; |
@@ -465,7 +465,7 @@ out: | |||
465 | } | 465 | } |
466 | 466 | ||
467 | static int hfsplus_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 467 | static int hfsplus_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
468 | struct nameidata *nd) | 468 | bool excl) |
469 | { | 469 | { |
470 | return hfsplus_mknod(dir, dentry, mode, 0); | 470 | return hfsplus_mknod(dir, dentry, mode, 0); |
471 | } | 471 | } |
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index 82b69ee4dacc..7009265b746f 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c | |||
@@ -168,7 +168,7 @@ const struct dentry_operations hfsplus_dentry_operations = { | |||
168 | }; | 168 | }; |
169 | 169 | ||
170 | static struct dentry *hfsplus_file_lookup(struct inode *dir, | 170 | static struct dentry *hfsplus_file_lookup(struct inode *dir, |
171 | struct dentry *dentry, struct nameidata *nd) | 171 | struct dentry *dentry, unsigned int flags) |
172 | { | 172 | { |
173 | struct hfs_find_data fd; | 173 | struct hfs_find_data fd; |
174 | struct super_block *sb = dir->i_sb; | 174 | struct super_block *sb = dir->i_sb; |
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index 2afa5bbccf9b..124146543aa7 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c | |||
@@ -553,7 +553,7 @@ static int read_name(struct inode *ino, char *name) | |||
553 | } | 553 | } |
554 | 554 | ||
555 | int hostfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 555 | int hostfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
556 | struct nameidata *nd) | 556 | bool excl) |
557 | { | 557 | { |
558 | struct inode *inode; | 558 | struct inode *inode; |
559 | char *name; | 559 | char *name; |
@@ -595,7 +595,7 @@ int hostfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | |||
595 | } | 595 | } |
596 | 596 | ||
597 | struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry, | 597 | struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry, |
598 | struct nameidata *nd) | 598 | unsigned int flags) |
599 | { | 599 | { |
600 | struct inode *inode; | 600 | struct inode *inode; |
601 | char *name; | 601 | char *name; |
diff --git a/fs/hpfs/dir.c b/fs/hpfs/dir.c index b8472f803f4e..78e12b2e0ea2 100644 --- a/fs/hpfs/dir.c +++ b/fs/hpfs/dir.c | |||
@@ -189,7 +189,7 @@ out: | |||
189 | * to tell read_inode to read fnode or not. | 189 | * to tell read_inode to read fnode or not. |
190 | */ | 190 | */ |
191 | 191 | ||
192 | struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | 192 | struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) |
193 | { | 193 | { |
194 | const unsigned char *name = dentry->d_name.name; | 194 | const unsigned char *name = dentry->d_name.name; |
195 | unsigned len = dentry->d_name.len; | 195 | unsigned len = dentry->d_name.len; |
diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h index c07ef1f1ced6..ac1ead194db5 100644 --- a/fs/hpfs/hpfs_fn.h +++ b/fs/hpfs/hpfs_fn.h | |||
@@ -220,7 +220,7 @@ extern const struct dentry_operations hpfs_dentry_operations; | |||
220 | 220 | ||
221 | /* dir.c */ | 221 | /* dir.c */ |
222 | 222 | ||
223 | struct dentry *hpfs_lookup(struct inode *, struct dentry *, struct nameidata *); | 223 | struct dentry *hpfs_lookup(struct inode *, struct dentry *, unsigned int); |
224 | extern const struct file_operations hpfs_dir_ops; | 224 | extern const struct file_operations hpfs_dir_ops; |
225 | 225 | ||
226 | /* dnode.c */ | 226 | /* dnode.c */ |
diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c index 9083ef8af58c..bc9082482f68 100644 --- a/fs/hpfs/namei.c +++ b/fs/hpfs/namei.c | |||
@@ -115,7 +115,7 @@ bail: | |||
115 | return err; | 115 | return err; |
116 | } | 116 | } |
117 | 117 | ||
118 | static int hpfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, struct nameidata *nd) | 118 | static int hpfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool excl) |
119 | { | 119 | { |
120 | const unsigned char *name = dentry->d_name.name; | 120 | const unsigned char *name = dentry->d_name.name; |
121 | unsigned len = dentry->d_name.len; | 121 | unsigned len = dentry->d_name.len; |
diff --git a/fs/hppfs/hppfs.c b/fs/hppfs/hppfs.c index d4f93b52cec5..e5c06531dcc4 100644 --- a/fs/hppfs/hppfs.c +++ b/fs/hppfs/hppfs.c | |||
@@ -138,7 +138,7 @@ static int file_removed(struct dentry *dentry, const char *file) | |||
138 | } | 138 | } |
139 | 139 | ||
140 | static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry, | 140 | static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry, |
141 | struct nameidata *nd) | 141 | unsigned int flags) |
142 | { | 142 | { |
143 | struct dentry *proc_dentry, *parent; | 143 | struct dentry *proc_dentry, *parent; |
144 | struct qstr *name = &dentry->d_name; | 144 | struct qstr *name = &dentry->d_name; |
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index cc9281b6c628..e13e9bdb0bf5 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
@@ -565,7 +565,7 @@ static int hugetlbfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mod | |||
565 | return retval; | 565 | return retval; |
566 | } | 566 | } |
567 | 567 | ||
568 | static int hugetlbfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, struct nameidata *nd) | 568 | static int hugetlbfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool excl) |
569 | { | 569 | { |
570 | return hugetlbfs_mknod(dir, dentry, mode | S_IFREG, 0); | 570 | return hugetlbfs_mknod(dir, dentry, mode | S_IFREG, 0); |
571 | } | 571 | } |
diff --git a/fs/inode.c b/fs/inode.c index c99163b1b310..775cbabd4fa5 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -182,7 +182,7 @@ int inode_init_always(struct super_block *sb, struct inode *inode) | |||
182 | } | 182 | } |
183 | inode->i_private = NULL; | 183 | inode->i_private = NULL; |
184 | inode->i_mapping = mapping; | 184 | inode->i_mapping = mapping; |
185 | INIT_LIST_HEAD(&inode->i_dentry); /* buggered by rcu freeing */ | 185 | INIT_HLIST_HEAD(&inode->i_dentry); /* buggered by rcu freeing */ |
186 | #ifdef CONFIG_FS_POSIX_ACL | 186 | #ifdef CONFIG_FS_POSIX_ACL |
187 | inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED; | 187 | inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED; |
188 | #endif | 188 | #endif |
diff --git a/fs/internal.h b/fs/internal.h index 18bc216ea09d..8a9f5fa840f1 100644 --- a/fs/internal.h +++ b/fs/internal.h | |||
@@ -50,8 +50,6 @@ extern int copy_mount_string(const void __user *, char **); | |||
50 | extern struct vfsmount *lookup_mnt(struct path *); | 50 | extern struct vfsmount *lookup_mnt(struct path *); |
51 | extern int finish_automount(struct vfsmount *, struct path *); | 51 | extern int finish_automount(struct vfsmount *, struct path *); |
52 | 52 | ||
53 | extern void mnt_make_longterm(struct vfsmount *); | ||
54 | extern void mnt_make_shortterm(struct vfsmount *); | ||
55 | extern int sb_prepare_remount_readonly(struct super_block *); | 53 | extern int sb_prepare_remount_readonly(struct super_block *); |
56 | 54 | ||
57 | extern void __init mnt_init(void); | 55 | extern void __init mnt_init(void); |
@@ -84,9 +82,6 @@ extern struct super_block *user_get_super(dev_t); | |||
84 | /* | 82 | /* |
85 | * open.c | 83 | * open.c |
86 | */ | 84 | */ |
87 | struct nameidata; | ||
88 | extern struct file *nameidata_to_filp(struct nameidata *); | ||
89 | extern void release_open_intent(struct nameidata *); | ||
90 | struct open_flags { | 85 | struct open_flags { |
91 | int open_flag; | 86 | int open_flag; |
92 | umode_t mode; | 87 | umode_t mode; |
diff --git a/fs/isofs/isofs.h b/fs/isofs/isofs.h index 0e73f63d9274..3620ad1ea9bc 100644 --- a/fs/isofs/isofs.h +++ b/fs/isofs/isofs.h | |||
@@ -114,7 +114,7 @@ extern int isofs_name_translate(struct iso_directory_record *, char *, struct in | |||
114 | int get_joliet_filename(struct iso_directory_record *, unsigned char *, struct inode *); | 114 | int get_joliet_filename(struct iso_directory_record *, unsigned char *, struct inode *); |
115 | int get_acorn_filename(struct iso_directory_record *, char *, struct inode *); | 115 | int get_acorn_filename(struct iso_directory_record *, char *, struct inode *); |
116 | 116 | ||
117 | extern struct dentry *isofs_lookup(struct inode *, struct dentry *, struct nameidata *); | 117 | extern struct dentry *isofs_lookup(struct inode *, struct dentry *, unsigned int flags); |
118 | extern struct buffer_head *isofs_bread(struct inode *, sector_t); | 118 | extern struct buffer_head *isofs_bread(struct inode *, sector_t); |
119 | extern int isofs_get_blocks(struct inode *, sector_t, struct buffer_head **, unsigned long); | 119 | extern int isofs_get_blocks(struct inode *, sector_t, struct buffer_head **, unsigned long); |
120 | 120 | ||
diff --git a/fs/isofs/namei.c b/fs/isofs/namei.c index 1e2946f2a69e..c167028844ed 100644 --- a/fs/isofs/namei.c +++ b/fs/isofs/namei.c | |||
@@ -163,7 +163,7 @@ isofs_find_entry(struct inode *dir, struct dentry *dentry, | |||
163 | return 0; | 163 | return 0; |
164 | } | 164 | } |
165 | 165 | ||
166 | struct dentry *isofs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | 166 | struct dentry *isofs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) |
167 | { | 167 | { |
168 | int found; | 168 | int found; |
169 | unsigned long uninitialized_var(block); | 169 | unsigned long uninitialized_var(block); |
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index b56018896d5e..23245191c5b5 100644 --- a/fs/jffs2/dir.c +++ b/fs/jffs2/dir.c | |||
@@ -25,9 +25,9 @@ | |||
25 | static int jffs2_readdir (struct file *, void *, filldir_t); | 25 | static int jffs2_readdir (struct file *, void *, filldir_t); |
26 | 26 | ||
27 | static int jffs2_create (struct inode *,struct dentry *,umode_t, | 27 | static int jffs2_create (struct inode *,struct dentry *,umode_t, |
28 | struct nameidata *); | 28 | bool); |
29 | static struct dentry *jffs2_lookup (struct inode *,struct dentry *, | 29 | static struct dentry *jffs2_lookup (struct inode *,struct dentry *, |
30 | struct nameidata *); | 30 | unsigned int); |
31 | static int jffs2_link (struct dentry *,struct inode *,struct dentry *); | 31 | static int jffs2_link (struct dentry *,struct inode *,struct dentry *); |
32 | static int jffs2_unlink (struct inode *,struct dentry *); | 32 | static int jffs2_unlink (struct inode *,struct dentry *); |
33 | static int jffs2_symlink (struct inode *,struct dentry *,const char *); | 33 | static int jffs2_symlink (struct inode *,struct dentry *,const char *); |
@@ -74,7 +74,7 @@ const struct inode_operations jffs2_dir_inode_operations = | |||
74 | nice and simple | 74 | nice and simple |
75 | */ | 75 | */ |
76 | static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target, | 76 | static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target, |
77 | struct nameidata *nd) | 77 | unsigned int flags) |
78 | { | 78 | { |
79 | struct jffs2_inode_info *dir_f; | 79 | struct jffs2_inode_info *dir_f; |
80 | struct jffs2_full_dirent *fd = NULL, *fd_list; | 80 | struct jffs2_full_dirent *fd = NULL, *fd_list; |
@@ -175,7 +175,7 @@ static int jffs2_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
175 | 175 | ||
176 | 176 | ||
177 | static int jffs2_create(struct inode *dir_i, struct dentry *dentry, | 177 | static int jffs2_create(struct inode *dir_i, struct dentry *dentry, |
178 | umode_t mode, struct nameidata *nd) | 178 | umode_t mode, bool excl) |
179 | { | 179 | { |
180 | struct jffs2_raw_inode *ri; | 180 | struct jffs2_raw_inode *ri; |
181 | struct jffs2_inode_info *f, *dir_f; | 181 | struct jffs2_inode_info *f, *dir_f; |
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 07c91ca6017d..c426293e16c1 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c | |||
@@ -73,7 +73,7 @@ static inline void free_ea_wmap(struct inode *inode) | |||
73 | * | 73 | * |
74 | */ | 74 | */ |
75 | static int jfs_create(struct inode *dip, struct dentry *dentry, umode_t mode, | 75 | static int jfs_create(struct inode *dip, struct dentry *dentry, umode_t mode, |
76 | struct nameidata *nd) | 76 | bool excl) |
77 | { | 77 | { |
78 | int rc = 0; | 78 | int rc = 0; |
79 | tid_t tid; /* transaction id */ | 79 | tid_t tid; /* transaction id */ |
@@ -1436,7 +1436,7 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry, | |||
1436 | return rc; | 1436 | return rc; |
1437 | } | 1437 | } |
1438 | 1438 | ||
1439 | static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry, struct nameidata *nd) | 1439 | static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry, unsigned int flags) |
1440 | { | 1440 | { |
1441 | struct btstack btstack; | 1441 | struct btstack btstack; |
1442 | ino_t inum; | 1442 | ino_t inum; |
@@ -1570,7 +1570,7 @@ out: | |||
1570 | return result; | 1570 | return result; |
1571 | } | 1571 | } |
1572 | 1572 | ||
1573 | static int jfs_ci_revalidate(struct dentry *dentry, struct nameidata *nd) | 1573 | static int jfs_ci_revalidate(struct dentry *dentry, unsigned int flags) |
1574 | { | 1574 | { |
1575 | /* | 1575 | /* |
1576 | * This is not negative dentry. Always valid. | 1576 | * This is not negative dentry. Always valid. |
@@ -1589,7 +1589,7 @@ static int jfs_ci_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
1589 | * This may be nfsd (or something), anyway, we can't see the | 1589 | * This may be nfsd (or something), anyway, we can't see the |
1590 | * intent of this. So, since this can be for creation, drop it. | 1590 | * intent of this. So, since this can be for creation, drop it. |
1591 | */ | 1591 | */ |
1592 | if (!nd) | 1592 | if (!flags) |
1593 | return 0; | 1593 | return 0; |
1594 | 1594 | ||
1595 | /* | 1595 | /* |
@@ -1597,7 +1597,7 @@ static int jfs_ci_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
1597 | * case sensitive name which is specified by user if this is | 1597 | * case sensitive name which is specified by user if this is |
1598 | * for creation. | 1598 | * for creation. |
1599 | */ | 1599 | */ |
1600 | if (nd->flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET)) | 1600 | if (flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET)) |
1601 | return 0; | 1601 | return 0; |
1602 | return 1; | 1602 | return 1; |
1603 | } | 1603 | } |
diff --git a/fs/libfs.c b/fs/libfs.c index f86ec27a4230..a74cb1725ac6 100644 --- a/fs/libfs.c +++ b/fs/libfs.c | |||
@@ -53,7 +53,7 @@ static int simple_delete_dentry(const struct dentry *dentry) | |||
53 | * Lookup the data. This is trivial - if the dentry didn't already | 53 | * Lookup the data. This is trivial - if the dentry didn't already |
54 | * exist, we know it is negative. Set d_op to delete negative dentries. | 54 | * exist, we know it is negative. Set d_op to delete negative dentries. |
55 | */ | 55 | */ |
56 | struct dentry *simple_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | 56 | struct dentry *simple_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) |
57 | { | 57 | { |
58 | static const struct dentry_operations simple_dentry_operations = { | 58 | static const struct dentry_operations simple_dentry_operations = { |
59 | .d_delete = simple_delete_dentry, | 59 | .d_delete = simple_delete_dentry, |
@@ -222,15 +222,15 @@ struct dentry *mount_pseudo(struct file_system_type *fs_type, char *name, | |||
222 | const struct super_operations *ops, | 222 | const struct super_operations *ops, |
223 | const struct dentry_operations *dops, unsigned long magic) | 223 | const struct dentry_operations *dops, unsigned long magic) |
224 | { | 224 | { |
225 | struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL); | 225 | struct super_block *s; |
226 | struct dentry *dentry; | 226 | struct dentry *dentry; |
227 | struct inode *root; | 227 | struct inode *root; |
228 | struct qstr d_name = QSTR_INIT(name, strlen(name)); | 228 | struct qstr d_name = QSTR_INIT(name, strlen(name)); |
229 | 229 | ||
230 | s = sget(fs_type, NULL, set_anon_super, MS_NOUSER, NULL); | ||
230 | if (IS_ERR(s)) | 231 | if (IS_ERR(s)) |
231 | return ERR_CAST(s); | 232 | return ERR_CAST(s); |
232 | 233 | ||
233 | s->s_flags = MS_NOUSER; | ||
234 | s->s_maxbytes = MAX_LFS_FILESIZE; | 234 | s->s_maxbytes = MAX_LFS_FILESIZE; |
235 | s->s_blocksize = PAGE_SIZE; | 235 | s->s_blocksize = PAGE_SIZE; |
236 | s->s_blocksize_bits = PAGE_SHIFT; | 236 | s->s_blocksize_bits = PAGE_SHIFT; |
diff --git a/fs/locks.c b/fs/locks.c index 814c51d0de47..fce6238d52c1 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -1465,7 +1465,7 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp) | |||
1465 | case F_WRLCK: | 1465 | case F_WRLCK: |
1466 | return generic_add_lease(filp, arg, flp); | 1466 | return generic_add_lease(filp, arg, flp); |
1467 | default: | 1467 | default: |
1468 | BUG(); | 1468 | return -EINVAL; |
1469 | } | 1469 | } |
1470 | } | 1470 | } |
1471 | EXPORT_SYMBOL(generic_setlease); | 1471 | EXPORT_SYMBOL(generic_setlease); |
diff --git a/fs/logfs/dir.c b/fs/logfs/dir.c index bea5d1b9954b..26e4a941532f 100644 --- a/fs/logfs/dir.c +++ b/fs/logfs/dir.c | |||
@@ -349,7 +349,7 @@ static void logfs_set_name(struct logfs_disk_dentry *dd, struct qstr *name) | |||
349 | } | 349 | } |
350 | 350 | ||
351 | static struct dentry *logfs_lookup(struct inode *dir, struct dentry *dentry, | 351 | static struct dentry *logfs_lookup(struct inode *dir, struct dentry *dentry, |
352 | struct nameidata *nd) | 352 | unsigned int flags) |
353 | { | 353 | { |
354 | struct page *page; | 354 | struct page *page; |
355 | struct logfs_disk_dentry *dd; | 355 | struct logfs_disk_dentry *dd; |
@@ -502,7 +502,7 @@ static int logfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
502 | } | 502 | } |
503 | 503 | ||
504 | static int logfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 504 | static int logfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
505 | struct nameidata *nd) | 505 | bool excl) |
506 | { | 506 | { |
507 | struct inode *inode; | 507 | struct inode *inode; |
508 | 508 | ||
diff --git a/fs/logfs/super.c b/fs/logfs/super.c index 97bca623d893..345c24b8a6f8 100644 --- a/fs/logfs/super.c +++ b/fs/logfs/super.c | |||
@@ -519,7 +519,7 @@ static struct dentry *logfs_get_sb_device(struct logfs_super *super, | |||
519 | log_super("LogFS: Start mount %x\n", mount_count++); | 519 | log_super("LogFS: Start mount %x\n", mount_count++); |
520 | 520 | ||
521 | err = -EINVAL; | 521 | err = -EINVAL; |
522 | sb = sget(type, logfs_sb_test, logfs_sb_set, super); | 522 | sb = sget(type, logfs_sb_test, logfs_sb_set, flags | MS_NOATIME, super); |
523 | if (IS_ERR(sb)) { | 523 | if (IS_ERR(sb)) { |
524 | super->s_devops->put_device(super); | 524 | super->s_devops->put_device(super); |
525 | kfree(super); | 525 | kfree(super); |
@@ -542,7 +542,6 @@ static struct dentry *logfs_get_sb_device(struct logfs_super *super, | |||
542 | sb->s_maxbytes = (1ull << 43) - 1; | 542 | sb->s_maxbytes = (1ull << 43) - 1; |
543 | sb->s_max_links = LOGFS_LINK_MAX; | 543 | sb->s_max_links = LOGFS_LINK_MAX; |
544 | sb->s_op = &logfs_super_operations; | 544 | sb->s_op = &logfs_super_operations; |
545 | sb->s_flags = flags | MS_NOATIME; | ||
546 | 545 | ||
547 | err = logfs_read_sb(sb, sb->s_flags & MS_RDONLY); | 546 | err = logfs_read_sb(sb, sb->s_flags & MS_RDONLY); |
548 | if (err) | 547 | if (err) |
diff --git a/fs/minix/namei.c b/fs/minix/namei.c index 2d0ee1786305..0db73d9dd668 100644 --- a/fs/minix/namei.c +++ b/fs/minix/namei.c | |||
@@ -18,7 +18,7 @@ static int add_nondir(struct dentry *dentry, struct inode *inode) | |||
18 | return err; | 18 | return err; |
19 | } | 19 | } |
20 | 20 | ||
21 | static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd) | 21 | static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry, unsigned int flags) |
22 | { | 22 | { |
23 | struct inode * inode = NULL; | 23 | struct inode * inode = NULL; |
24 | ino_t ino; | 24 | ino_t ino; |
@@ -55,7 +55,7 @@ static int minix_mknod(struct inode * dir, struct dentry *dentry, umode_t mode, | |||
55 | } | 55 | } |
56 | 56 | ||
57 | static int minix_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 57 | static int minix_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
58 | struct nameidata *nd) | 58 | bool excl) |
59 | { | 59 | { |
60 | return minix_mknod(dir, dentry, mode, 0); | 60 | return minix_mknod(dir, dentry, mode, 0); |
61 | } | 61 | } |
diff --git a/fs/mount.h b/fs/mount.h index 4ef36d93e5a2..4f291f9de641 100644 --- a/fs/mount.h +++ b/fs/mount.h | |||
@@ -22,7 +22,6 @@ struct mount { | |||
22 | struct vfsmount mnt; | 22 | struct vfsmount mnt; |
23 | #ifdef CONFIG_SMP | 23 | #ifdef CONFIG_SMP |
24 | struct mnt_pcp __percpu *mnt_pcp; | 24 | struct mnt_pcp __percpu *mnt_pcp; |
25 | atomic_t mnt_longterm; /* how many of the refs are longterm */ | ||
26 | #else | 25 | #else |
27 | int mnt_count; | 26 | int mnt_count; |
28 | int mnt_writers; | 27 | int mnt_writers; |
@@ -49,6 +48,8 @@ struct mount { | |||
49 | int mnt_ghosts; | 48 | int mnt_ghosts; |
50 | }; | 49 | }; |
51 | 50 | ||
51 | #define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */ | ||
52 | |||
52 | static inline struct mount *real_mount(struct vfsmount *mnt) | 53 | static inline struct mount *real_mount(struct vfsmount *mnt) |
53 | { | 54 | { |
54 | return container_of(mnt, struct mount, mnt); | 55 | return container_of(mnt, struct mount, mnt); |
@@ -59,6 +60,12 @@ static inline int mnt_has_parent(struct mount *mnt) | |||
59 | return mnt != mnt->mnt_parent; | 60 | return mnt != mnt->mnt_parent; |
60 | } | 61 | } |
61 | 62 | ||
63 | static inline int is_mounted(struct vfsmount *mnt) | ||
64 | { | ||
65 | /* neither detached nor internal? */ | ||
66 | return !IS_ERR_OR_NULL(real_mount(mnt)); | ||
67 | } | ||
68 | |||
62 | extern struct mount *__lookup_mnt(struct vfsmount *, struct dentry *, int); | 69 | extern struct mount *__lookup_mnt(struct vfsmount *, struct dentry *, int); |
63 | 70 | ||
64 | static inline void get_mnt_ns(struct mnt_namespace *ns) | 71 | static inline void get_mnt_ns(struct mnt_namespace *ns) |
@@ -67,10 +74,12 @@ static inline void get_mnt_ns(struct mnt_namespace *ns) | |||
67 | } | 74 | } |
68 | 75 | ||
69 | struct proc_mounts { | 76 | struct proc_mounts { |
70 | struct seq_file m; /* must be the first element */ | 77 | struct seq_file m; |
71 | struct mnt_namespace *ns; | 78 | struct mnt_namespace *ns; |
72 | struct path root; | 79 | struct path root; |
73 | int (*show)(struct seq_file *, struct vfsmount *); | 80 | int (*show)(struct seq_file *, struct vfsmount *); |
74 | }; | 81 | }; |
75 | 82 | ||
83 | #define proc_mounts(p) (container_of((p), struct proc_mounts, m)) | ||
84 | |||
76 | extern const struct seq_operations mounts_op; | 85 | extern const struct seq_operations mounts_op; |
diff --git a/fs/namei.c b/fs/namei.c index 7d694194024a..c6dcb4c8f86c 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -463,25 +463,9 @@ err_root: | |||
463 | return -ECHILD; | 463 | return -ECHILD; |
464 | } | 464 | } |
465 | 465 | ||
466 | /** | 466 | static inline int d_revalidate(struct dentry *dentry, unsigned int flags) |
467 | * release_open_intent - free up open intent resources | ||
468 | * @nd: pointer to nameidata | ||
469 | */ | ||
470 | void release_open_intent(struct nameidata *nd) | ||
471 | { | 467 | { |
472 | struct file *file = nd->intent.open.file; | 468 | return dentry->d_op->d_revalidate(dentry, flags); |
473 | |||
474 | if (file && !IS_ERR(file)) { | ||
475 | if (file->f_path.dentry == NULL) | ||
476 | put_filp(file); | ||
477 | else | ||
478 | fput(file); | ||
479 | } | ||
480 | } | ||
481 | |||
482 | static inline int d_revalidate(struct dentry *dentry, struct nameidata *nd) | ||
483 | { | ||
484 | return dentry->d_op->d_revalidate(dentry, nd); | ||
485 | } | 469 | } |
486 | 470 | ||
487 | /** | 471 | /** |
@@ -527,7 +511,7 @@ static int complete_walk(struct nameidata *nd) | |||
527 | return 0; | 511 | return 0; |
528 | 512 | ||
529 | /* Note: we do not d_invalidate() */ | 513 | /* Note: we do not d_invalidate() */ |
530 | status = d_revalidate(dentry, nd); | 514 | status = d_revalidate(dentry, nd->flags); |
531 | if (status > 0) | 515 | if (status > 0) |
532 | return 0; | 516 | return 0; |
533 | 517 | ||
@@ -602,10 +586,25 @@ static inline void path_to_nameidata(const struct path *path, | |||
602 | nd->path.dentry = path->dentry; | 586 | nd->path.dentry = path->dentry; |
603 | } | 587 | } |
604 | 588 | ||
589 | /* | ||
590 | * Helper to directly jump to a known parsed path from ->follow_link, | ||
591 | * caller must have taken a reference to path beforehand. | ||
592 | */ | ||
593 | void nd_jump_link(struct nameidata *nd, struct path *path) | ||
594 | { | ||
595 | path_put(&nd->path); | ||
596 | |||
597 | nd->path = *path; | ||
598 | nd->inode = nd->path.dentry->d_inode; | ||
599 | nd->flags |= LOOKUP_JUMPED; | ||
600 | |||
601 | BUG_ON(nd->inode->i_op->follow_link); | ||
602 | } | ||
603 | |||
605 | static inline void put_link(struct nameidata *nd, struct path *link, void *cookie) | 604 | static inline void put_link(struct nameidata *nd, struct path *link, void *cookie) |
606 | { | 605 | { |
607 | struct inode *inode = link->dentry->d_inode; | 606 | struct inode *inode = link->dentry->d_inode; |
608 | if (!IS_ERR(cookie) && inode->i_op->put_link) | 607 | if (inode->i_op->put_link) |
609 | inode->i_op->put_link(link->dentry, nd, cookie); | 608 | inode->i_op->put_link(link->dentry, nd, cookie); |
610 | path_put(link); | 609 | path_put(link); |
611 | } | 610 | } |
@@ -613,19 +612,19 @@ static inline void put_link(struct nameidata *nd, struct path *link, void *cooki | |||
613 | static __always_inline int | 612 | static __always_inline int |
614 | follow_link(struct path *link, struct nameidata *nd, void **p) | 613 | follow_link(struct path *link, struct nameidata *nd, void **p) |
615 | { | 614 | { |
616 | int error; | ||
617 | struct dentry *dentry = link->dentry; | 615 | struct dentry *dentry = link->dentry; |
616 | int error; | ||
617 | char *s; | ||
618 | 618 | ||
619 | BUG_ON(nd->flags & LOOKUP_RCU); | 619 | BUG_ON(nd->flags & LOOKUP_RCU); |
620 | 620 | ||
621 | if (link->mnt == nd->path.mnt) | 621 | if (link->mnt == nd->path.mnt) |
622 | mntget(link->mnt); | 622 | mntget(link->mnt); |
623 | 623 | ||
624 | if (unlikely(current->total_link_count >= 40)) { | 624 | error = -ELOOP; |
625 | *p = ERR_PTR(-ELOOP); /* no ->put_link(), please */ | 625 | if (unlikely(current->total_link_count >= 40)) |
626 | path_put(&nd->path); | 626 | goto out_put_nd_path; |
627 | return -ELOOP; | 627 | |
628 | } | ||
629 | cond_resched(); | 628 | cond_resched(); |
630 | current->total_link_count++; | 629 | current->total_link_count++; |
631 | 630 | ||
@@ -633,30 +632,28 @@ follow_link(struct path *link, struct nameidata *nd, void **p) | |||
633 | nd_set_link(nd, NULL); | 632 | nd_set_link(nd, NULL); |
634 | 633 | ||
635 | error = security_inode_follow_link(link->dentry, nd); | 634 | error = security_inode_follow_link(link->dentry, nd); |
636 | if (error) { | 635 | if (error) |
637 | *p = ERR_PTR(error); /* no ->put_link(), please */ | 636 | goto out_put_nd_path; |
638 | path_put(&nd->path); | ||
639 | return error; | ||
640 | } | ||
641 | 637 | ||
642 | nd->last_type = LAST_BIND; | 638 | nd->last_type = LAST_BIND; |
643 | *p = dentry->d_inode->i_op->follow_link(dentry, nd); | 639 | *p = dentry->d_inode->i_op->follow_link(dentry, nd); |
644 | error = PTR_ERR(*p); | 640 | error = PTR_ERR(*p); |
645 | if (!IS_ERR(*p)) { | 641 | if (IS_ERR(*p)) |
646 | char *s = nd_get_link(nd); | 642 | goto out_put_nd_path; |
647 | error = 0; | 643 | |
648 | if (s) | 644 | error = 0; |
649 | error = __vfs_follow_link(nd, s); | 645 | s = nd_get_link(nd); |
650 | else if (nd->last_type == LAST_BIND) { | 646 | if (s) { |
651 | nd->flags |= LOOKUP_JUMPED; | 647 | error = __vfs_follow_link(nd, s); |
652 | nd->inode = nd->path.dentry->d_inode; | 648 | if (unlikely(error)) |
653 | if (nd->inode->i_op->follow_link) { | 649 | put_link(nd, link, *p); |
654 | /* stepped on a _really_ weird one */ | ||
655 | path_put(&nd->path); | ||
656 | error = -ELOOP; | ||
657 | } | ||
658 | } | ||
659 | } | 650 | } |
651 | |||
652 | return error; | ||
653 | |||
654 | out_put_nd_path: | ||
655 | path_put(&nd->path); | ||
656 | path_put(link); | ||
660 | return error; | 657 | return error; |
661 | } | 658 | } |
662 | 659 | ||
@@ -675,6 +672,16 @@ static int follow_up_rcu(struct path *path) | |||
675 | return 1; | 672 | return 1; |
676 | } | 673 | } |
677 | 674 | ||
675 | /* | ||
676 | * follow_up - Find the mountpoint of path's vfsmount | ||
677 | * | ||
678 | * Given a path, find the mountpoint of its source file system. | ||
679 | * Replace @path with the path of the mountpoint in the parent mount. | ||
680 | * Up is towards /. | ||
681 | * | ||
682 | * Return 1 if we went up a level and 0 if we were already at the | ||
683 | * root. | ||
684 | */ | ||
678 | int follow_up(struct path *path) | 685 | int follow_up(struct path *path) |
679 | { | 686 | { |
680 | struct mount *mnt = real_mount(path->mnt); | 687 | struct mount *mnt = real_mount(path->mnt); |
@@ -1048,7 +1055,7 @@ static void follow_dotdot(struct nameidata *nd) | |||
1048 | * dir->d_inode->i_mutex must be held | 1055 | * dir->d_inode->i_mutex must be held |
1049 | */ | 1056 | */ |
1050 | static struct dentry *lookup_dcache(struct qstr *name, struct dentry *dir, | 1057 | static struct dentry *lookup_dcache(struct qstr *name, struct dentry *dir, |
1051 | struct nameidata *nd, bool *need_lookup) | 1058 | unsigned int flags, bool *need_lookup) |
1052 | { | 1059 | { |
1053 | struct dentry *dentry; | 1060 | struct dentry *dentry; |
1054 | int error; | 1061 | int error; |
@@ -1059,7 +1066,7 @@ static struct dentry *lookup_dcache(struct qstr *name, struct dentry *dir, | |||
1059 | if (d_need_lookup(dentry)) { | 1066 | if (d_need_lookup(dentry)) { |
1060 | *need_lookup = true; | 1067 | *need_lookup = true; |
1061 | } else if (dentry->d_flags & DCACHE_OP_REVALIDATE) { | 1068 | } else if (dentry->d_flags & DCACHE_OP_REVALIDATE) { |
1062 | error = d_revalidate(dentry, nd); | 1069 | error = d_revalidate(dentry, flags); |
1063 | if (unlikely(error <= 0)) { | 1070 | if (unlikely(error <= 0)) { |
1064 | if (error < 0) { | 1071 | if (error < 0) { |
1065 | dput(dentry); | 1072 | dput(dentry); |
@@ -1089,7 +1096,7 @@ static struct dentry *lookup_dcache(struct qstr *name, struct dentry *dir, | |||
1089 | * dir->d_inode->i_mutex must be held | 1096 | * dir->d_inode->i_mutex must be held |
1090 | */ | 1097 | */ |
1091 | static struct dentry *lookup_real(struct inode *dir, struct dentry *dentry, | 1098 | static struct dentry *lookup_real(struct inode *dir, struct dentry *dentry, |
1092 | struct nameidata *nd) | 1099 | unsigned int flags) |
1093 | { | 1100 | { |
1094 | struct dentry *old; | 1101 | struct dentry *old; |
1095 | 1102 | ||
@@ -1099,7 +1106,7 @@ static struct dentry *lookup_real(struct inode *dir, struct dentry *dentry, | |||
1099 | return ERR_PTR(-ENOENT); | 1106 | return ERR_PTR(-ENOENT); |
1100 | } | 1107 | } |
1101 | 1108 | ||
1102 | old = dir->i_op->lookup(dir, dentry, nd); | 1109 | old = dir->i_op->lookup(dir, dentry, flags); |
1103 | if (unlikely(old)) { | 1110 | if (unlikely(old)) { |
1104 | dput(dentry); | 1111 | dput(dentry); |
1105 | dentry = old; | 1112 | dentry = old; |
@@ -1108,16 +1115,16 @@ static struct dentry *lookup_real(struct inode *dir, struct dentry *dentry, | |||
1108 | } | 1115 | } |
1109 | 1116 | ||
1110 | static struct dentry *__lookup_hash(struct qstr *name, | 1117 | static struct dentry *__lookup_hash(struct qstr *name, |
1111 | struct dentry *base, struct nameidata *nd) | 1118 | struct dentry *base, unsigned int flags) |
1112 | { | 1119 | { |
1113 | bool need_lookup; | 1120 | bool need_lookup; |
1114 | struct dentry *dentry; | 1121 | struct dentry *dentry; |
1115 | 1122 | ||
1116 | dentry = lookup_dcache(name, base, nd, &need_lookup); | 1123 | dentry = lookup_dcache(name, base, flags, &need_lookup); |
1117 | if (!need_lookup) | 1124 | if (!need_lookup) |
1118 | return dentry; | 1125 | return dentry; |
1119 | 1126 | ||
1120 | return lookup_real(base->d_inode, dentry, nd); | 1127 | return lookup_real(base->d_inode, dentry, flags); |
1121 | } | 1128 | } |
1122 | 1129 | ||
1123 | /* | 1130 | /* |
@@ -1167,7 +1174,7 @@ static int lookup_fast(struct nameidata *nd, struct qstr *name, | |||
1167 | if (unlikely(d_need_lookup(dentry))) | 1174 | if (unlikely(d_need_lookup(dentry))) |
1168 | goto unlazy; | 1175 | goto unlazy; |
1169 | if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE)) { | 1176 | if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE)) { |
1170 | status = d_revalidate(dentry, nd); | 1177 | status = d_revalidate(dentry, nd->flags); |
1171 | if (unlikely(status <= 0)) { | 1178 | if (unlikely(status <= 0)) { |
1172 | if (status != -ECHILD) | 1179 | if (status != -ECHILD) |
1173 | need_reval = 0; | 1180 | need_reval = 0; |
@@ -1197,7 +1204,7 @@ unlazy: | |||
1197 | } | 1204 | } |
1198 | 1205 | ||
1199 | if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE) && need_reval) | 1206 | if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE) && need_reval) |
1200 | status = d_revalidate(dentry, nd); | 1207 | status = d_revalidate(dentry, nd->flags); |
1201 | if (unlikely(status <= 0)) { | 1208 | if (unlikely(status <= 0)) { |
1202 | if (status < 0) { | 1209 | if (status < 0) { |
1203 | dput(dentry); | 1210 | dput(dentry); |
@@ -1236,7 +1243,7 @@ static int lookup_slow(struct nameidata *nd, struct qstr *name, | |||
1236 | BUG_ON(nd->inode != parent->d_inode); | 1243 | BUG_ON(nd->inode != parent->d_inode); |
1237 | 1244 | ||
1238 | mutex_lock(&parent->d_inode->i_mutex); | 1245 | mutex_lock(&parent->d_inode->i_mutex); |
1239 | dentry = __lookup_hash(name, parent, nd); | 1246 | dentry = __lookup_hash(name, parent, nd->flags); |
1240 | mutex_unlock(&parent->d_inode->i_mutex); | 1247 | mutex_unlock(&parent->d_inode->i_mutex); |
1241 | if (IS_ERR(dentry)) | 1248 | if (IS_ERR(dentry)) |
1242 | return PTR_ERR(dentry); | 1249 | return PTR_ERR(dentry); |
@@ -1383,9 +1390,10 @@ static inline int nested_symlink(struct path *path, struct nameidata *nd) | |||
1383 | void *cookie; | 1390 | void *cookie; |
1384 | 1391 | ||
1385 | res = follow_link(&link, nd, &cookie); | 1392 | res = follow_link(&link, nd, &cookie); |
1386 | if (!res) | 1393 | if (res) |
1387 | res = walk_component(nd, path, &nd->last, | 1394 | break; |
1388 | nd->last_type, LOOKUP_FOLLOW); | 1395 | res = walk_component(nd, path, &nd->last, |
1396 | nd->last_type, LOOKUP_FOLLOW); | ||
1389 | put_link(nd, &link, cookie); | 1397 | put_link(nd, &link, cookie); |
1390 | } while (res > 0); | 1398 | } while (res > 0); |
1391 | 1399 | ||
@@ -1777,8 +1785,9 @@ static int path_lookupat(int dfd, const char *name, | |||
1777 | struct path link = path; | 1785 | struct path link = path; |
1778 | nd->flags |= LOOKUP_PARENT; | 1786 | nd->flags |= LOOKUP_PARENT; |
1779 | err = follow_link(&link, nd, &cookie); | 1787 | err = follow_link(&link, nd, &cookie); |
1780 | if (!err) | 1788 | if (err) |
1781 | err = lookup_last(nd, &path); | 1789 | break; |
1790 | err = lookup_last(nd, &path); | ||
1782 | put_link(nd, &link, cookie); | 1791 | put_link(nd, &link, cookie); |
1783 | } | 1792 | } |
1784 | } | 1793 | } |
@@ -1821,9 +1830,27 @@ static int do_path_lookup(int dfd, const char *name, | |||
1821 | return retval; | 1830 | return retval; |
1822 | } | 1831 | } |
1823 | 1832 | ||
1824 | int kern_path_parent(const char *name, struct nameidata *nd) | 1833 | /* does lookup, returns the object with parent locked */ |
1834 | struct dentry *kern_path_locked(const char *name, struct path *path) | ||
1825 | { | 1835 | { |
1826 | return do_path_lookup(AT_FDCWD, name, LOOKUP_PARENT, nd); | 1836 | struct nameidata nd; |
1837 | struct dentry *d; | ||
1838 | int err = do_path_lookup(AT_FDCWD, name, LOOKUP_PARENT, &nd); | ||
1839 | if (err) | ||
1840 | return ERR_PTR(err); | ||
1841 | if (nd.last_type != LAST_NORM) { | ||
1842 | path_put(&nd.path); | ||
1843 | return ERR_PTR(-EINVAL); | ||
1844 | } | ||
1845 | mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT); | ||
1846 | d = lookup_one_len(nd.last.name, nd.path.dentry, nd.last.len); | ||
1847 | if (IS_ERR(d)) { | ||
1848 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | ||
1849 | path_put(&nd.path); | ||
1850 | return d; | ||
1851 | } | ||
1852 | *path = nd.path; | ||
1853 | return d; | ||
1827 | } | 1854 | } |
1828 | 1855 | ||
1829 | int kern_path(const char *name, unsigned int flags, struct path *path) | 1856 | int kern_path(const char *name, unsigned int flags, struct path *path) |
@@ -1866,7 +1893,7 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt, | |||
1866 | */ | 1893 | */ |
1867 | static struct dentry *lookup_hash(struct nameidata *nd) | 1894 | static struct dentry *lookup_hash(struct nameidata *nd) |
1868 | { | 1895 | { |
1869 | return __lookup_hash(&nd->last, nd->path.dentry, nd); | 1896 | return __lookup_hash(&nd->last, nd->path.dentry, nd->flags); |
1870 | } | 1897 | } |
1871 | 1898 | ||
1872 | /** | 1899 | /** |
@@ -1913,7 +1940,7 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len) | |||
1913 | if (err) | 1940 | if (err) |
1914 | return ERR_PTR(err); | 1941 | return ERR_PTR(err); |
1915 | 1942 | ||
1916 | return __lookup_hash(&this, base, NULL); | 1943 | return __lookup_hash(&this, base, 0); |
1917 | } | 1944 | } |
1918 | 1945 | ||
1919 | int user_path_at_empty(int dfd, const char __user *name, unsigned flags, | 1946 | int user_path_at_empty(int dfd, const char __user *name, unsigned flags, |
@@ -2086,10 +2113,9 @@ void unlock_rename(struct dentry *p1, struct dentry *p2) | |||
2086 | } | 2113 | } |
2087 | 2114 | ||
2088 | int vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 2115 | int vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
2089 | struct nameidata *nd) | 2116 | bool want_excl) |
2090 | { | 2117 | { |
2091 | int error = may_create(dir, dentry); | 2118 | int error = may_create(dir, dentry); |
2092 | |||
2093 | if (error) | 2119 | if (error) |
2094 | return error; | 2120 | return error; |
2095 | 2121 | ||
@@ -2100,7 +2126,7 @@ int vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | |||
2100 | error = security_inode_create(dir, dentry, mode); | 2126 | error = security_inode_create(dir, dentry, mode); |
2101 | if (error) | 2127 | if (error) |
2102 | return error; | 2128 | return error; |
2103 | error = dir->i_op->create(dir, dentry, mode, nd); | 2129 | error = dir->i_op->create(dir, dentry, mode, want_excl); |
2104 | if (!error) | 2130 | if (!error) |
2105 | fsnotify_create(dir, dentry); | 2131 | fsnotify_create(dir, dentry); |
2106 | return error; | 2132 | return error; |
@@ -2187,21 +2213,275 @@ static inline int open_to_namei_flags(int flag) | |||
2187 | return flag; | 2213 | return flag; |
2188 | } | 2214 | } |
2189 | 2215 | ||
2216 | static int may_o_create(struct path *dir, struct dentry *dentry, umode_t mode) | ||
2217 | { | ||
2218 | int error = security_path_mknod(dir, dentry, mode, 0); | ||
2219 | if (error) | ||
2220 | return error; | ||
2221 | |||
2222 | error = inode_permission(dir->dentry->d_inode, MAY_WRITE | MAY_EXEC); | ||
2223 | if (error) | ||
2224 | return error; | ||
2225 | |||
2226 | return security_inode_create(dir->dentry->d_inode, dentry, mode); | ||
2227 | } | ||
2228 | |||
2190 | /* | 2229 | /* |
2191 | * Handle the last step of open() | 2230 | * Attempt to atomically look up, create and open a file from a negative |
2231 | * dentry. | ||
2232 | * | ||
2233 | * Returns 0 if successful. The file will have been created and attached to | ||
2234 | * @file by the filesystem calling finish_open(). | ||
2235 | * | ||
2236 | * Returns 1 if the file was looked up only or didn't need creating. The | ||
2237 | * caller will need to perform the open themselves. @path will have been | ||
2238 | * updated to point to the new dentry. This may be negative. | ||
2239 | * | ||
2240 | * Returns an error code otherwise. | ||
2192 | */ | 2241 | */ |
2193 | static struct file *do_last(struct nameidata *nd, struct path *path, | 2242 | static int atomic_open(struct nameidata *nd, struct dentry *dentry, |
2194 | const struct open_flags *op, const char *pathname) | 2243 | struct path *path, struct file *file, |
2244 | const struct open_flags *op, | ||
2245 | bool *want_write, bool need_lookup, | ||
2246 | int *opened) | ||
2247 | { | ||
2248 | struct inode *dir = nd->path.dentry->d_inode; | ||
2249 | unsigned open_flag = open_to_namei_flags(op->open_flag); | ||
2250 | umode_t mode; | ||
2251 | int error; | ||
2252 | int acc_mode; | ||
2253 | int create_error = 0; | ||
2254 | struct dentry *const DENTRY_NOT_SET = (void *) -1UL; | ||
2255 | |||
2256 | BUG_ON(dentry->d_inode); | ||
2257 | |||
2258 | /* Don't create child dentry for a dead directory. */ | ||
2259 | if (unlikely(IS_DEADDIR(dir))) { | ||
2260 | error = -ENOENT; | ||
2261 | goto out; | ||
2262 | } | ||
2263 | |||
2264 | mode = op->mode & S_IALLUGO; | ||
2265 | if ((open_flag & O_CREAT) && !IS_POSIXACL(dir)) | ||
2266 | mode &= ~current_umask(); | ||
2267 | |||
2268 | if (open_flag & O_EXCL) { | ||
2269 | open_flag &= ~O_TRUNC; | ||
2270 | *opened |= FILE_CREATED; | ||
2271 | } | ||
2272 | |||
2273 | /* | ||
2274 | * Checking write permission is tricky, bacuse we don't know if we are | ||
2275 | * going to actually need it: O_CREAT opens should work as long as the | ||
2276 | * file exists. But checking existence breaks atomicity. The trick is | ||
2277 | * to check access and if not granted clear O_CREAT from the flags. | ||
2278 | * | ||
2279 | * Another problem is returing the "right" error value (e.g. for an | ||
2280 | * O_EXCL open we want to return EEXIST not EROFS). | ||
2281 | */ | ||
2282 | if ((open_flag & (O_CREAT | O_TRUNC)) || | ||
2283 | (open_flag & O_ACCMODE) != O_RDONLY) { | ||
2284 | error = mnt_want_write(nd->path.mnt); | ||
2285 | if (!error) { | ||
2286 | *want_write = true; | ||
2287 | } else if (!(open_flag & O_CREAT)) { | ||
2288 | /* | ||
2289 | * No O_CREATE -> atomicity not a requirement -> fall | ||
2290 | * back to lookup + open | ||
2291 | */ | ||
2292 | goto no_open; | ||
2293 | } else if (open_flag & (O_EXCL | O_TRUNC)) { | ||
2294 | /* Fall back and fail with the right error */ | ||
2295 | create_error = error; | ||
2296 | goto no_open; | ||
2297 | } else { | ||
2298 | /* No side effects, safe to clear O_CREAT */ | ||
2299 | create_error = error; | ||
2300 | open_flag &= ~O_CREAT; | ||
2301 | } | ||
2302 | } | ||
2303 | |||
2304 | if (open_flag & O_CREAT) { | ||
2305 | error = may_o_create(&nd->path, dentry, op->mode); | ||
2306 | if (error) { | ||
2307 | create_error = error; | ||
2308 | if (open_flag & O_EXCL) | ||
2309 | goto no_open; | ||
2310 | open_flag &= ~O_CREAT; | ||
2311 | } | ||
2312 | } | ||
2313 | |||
2314 | if (nd->flags & LOOKUP_DIRECTORY) | ||
2315 | open_flag |= O_DIRECTORY; | ||
2316 | |||
2317 | file->f_path.dentry = DENTRY_NOT_SET; | ||
2318 | file->f_path.mnt = nd->path.mnt; | ||
2319 | error = dir->i_op->atomic_open(dir, dentry, file, open_flag, mode, | ||
2320 | opened); | ||
2321 | if (error < 0) { | ||
2322 | if (create_error && error == -ENOENT) | ||
2323 | error = create_error; | ||
2324 | goto out; | ||
2325 | } | ||
2326 | |||
2327 | acc_mode = op->acc_mode; | ||
2328 | if (*opened & FILE_CREATED) { | ||
2329 | fsnotify_create(dir, dentry); | ||
2330 | acc_mode = MAY_OPEN; | ||
2331 | } | ||
2332 | |||
2333 | if (error) { /* returned 1, that is */ | ||
2334 | if (WARN_ON(file->f_path.dentry == DENTRY_NOT_SET)) { | ||
2335 | error = -EIO; | ||
2336 | goto out; | ||
2337 | } | ||
2338 | if (file->f_path.dentry) { | ||
2339 | dput(dentry); | ||
2340 | dentry = file->f_path.dentry; | ||
2341 | } | ||
2342 | goto looked_up; | ||
2343 | } | ||
2344 | |||
2345 | /* | ||
2346 | * We didn't have the inode before the open, so check open permission | ||
2347 | * here. | ||
2348 | */ | ||
2349 | error = may_open(&file->f_path, acc_mode, open_flag); | ||
2350 | if (error) | ||
2351 | fput(file); | ||
2352 | |||
2353 | out: | ||
2354 | dput(dentry); | ||
2355 | return error; | ||
2356 | |||
2357 | no_open: | ||
2358 | if (need_lookup) { | ||
2359 | dentry = lookup_real(dir, dentry, nd->flags); | ||
2360 | if (IS_ERR(dentry)) | ||
2361 | return PTR_ERR(dentry); | ||
2362 | |||
2363 | if (create_error) { | ||
2364 | int open_flag = op->open_flag; | ||
2365 | |||
2366 | error = create_error; | ||
2367 | if ((open_flag & O_EXCL)) { | ||
2368 | if (!dentry->d_inode) | ||
2369 | goto out; | ||
2370 | } else if (!dentry->d_inode) { | ||
2371 | goto out; | ||
2372 | } else if ((open_flag & O_TRUNC) && | ||
2373 | S_ISREG(dentry->d_inode->i_mode)) { | ||
2374 | goto out; | ||
2375 | } | ||
2376 | /* will fail later, go on to get the right error */ | ||
2377 | } | ||
2378 | } | ||
2379 | looked_up: | ||
2380 | path->dentry = dentry; | ||
2381 | path->mnt = nd->path.mnt; | ||
2382 | return 1; | ||
2383 | } | ||
2384 | |||
2385 | /* | ||
2386 | * Look up and maybe create and open the last component. | ||
2387 | * | ||
2388 | * Must be called with i_mutex held on parent. | ||
2389 | * | ||
2390 | * Returns 0 if the file was successfully atomically created (if necessary) and | ||
2391 | * opened. In this case the file will be returned attached to @file. | ||
2392 | * | ||
2393 | * Returns 1 if the file was not completely opened at this time, though lookups | ||
2394 | * and creations will have been performed and the dentry returned in @path will | ||
2395 | * be positive upon return if O_CREAT was specified. If O_CREAT wasn't | ||
2396 | * specified then a negative dentry may be returned. | ||
2397 | * | ||
2398 | * An error code is returned otherwise. | ||
2399 | * | ||
2400 | * FILE_CREATE will be set in @*opened if the dentry was created and will be | ||
2401 | * cleared otherwise prior to returning. | ||
2402 | */ | ||
2403 | static int lookup_open(struct nameidata *nd, struct path *path, | ||
2404 | struct file *file, | ||
2405 | const struct open_flags *op, | ||
2406 | bool *want_write, int *opened) | ||
2195 | { | 2407 | { |
2196 | struct dentry *dir = nd->path.dentry; | 2408 | struct dentry *dir = nd->path.dentry; |
2409 | struct inode *dir_inode = dir->d_inode; | ||
2197 | struct dentry *dentry; | 2410 | struct dentry *dentry; |
2411 | int error; | ||
2412 | bool need_lookup; | ||
2413 | |||
2414 | *opened &= ~FILE_CREATED; | ||
2415 | dentry = lookup_dcache(&nd->last, dir, nd->flags, &need_lookup); | ||
2416 | if (IS_ERR(dentry)) | ||
2417 | return PTR_ERR(dentry); | ||
2418 | |||
2419 | /* Cached positive dentry: will open in f_op->open */ | ||
2420 | if (!need_lookup && dentry->d_inode) | ||
2421 | goto out_no_open; | ||
2422 | |||
2423 | if ((nd->flags & LOOKUP_OPEN) && dir_inode->i_op->atomic_open) { | ||
2424 | return atomic_open(nd, dentry, path, file, op, want_write, | ||
2425 | need_lookup, opened); | ||
2426 | } | ||
2427 | |||
2428 | if (need_lookup) { | ||
2429 | BUG_ON(dentry->d_inode); | ||
2430 | |||
2431 | dentry = lookup_real(dir_inode, dentry, nd->flags); | ||
2432 | if (IS_ERR(dentry)) | ||
2433 | return PTR_ERR(dentry); | ||
2434 | } | ||
2435 | |||
2436 | /* Negative dentry, just create the file */ | ||
2437 | if (!dentry->d_inode && (op->open_flag & O_CREAT)) { | ||
2438 | umode_t mode = op->mode; | ||
2439 | if (!IS_POSIXACL(dir->d_inode)) | ||
2440 | mode &= ~current_umask(); | ||
2441 | /* | ||
2442 | * This write is needed to ensure that a | ||
2443 | * rw->ro transition does not occur between | ||
2444 | * the time when the file is created and when | ||
2445 | * a permanent write count is taken through | ||
2446 | * the 'struct file' in finish_open(). | ||
2447 | */ | ||
2448 | error = mnt_want_write(nd->path.mnt); | ||
2449 | if (error) | ||
2450 | goto out_dput; | ||
2451 | *want_write = true; | ||
2452 | *opened |= FILE_CREATED; | ||
2453 | error = security_path_mknod(&nd->path, dentry, mode, 0); | ||
2454 | if (error) | ||
2455 | goto out_dput; | ||
2456 | error = vfs_create(dir->d_inode, dentry, mode, | ||
2457 | nd->flags & LOOKUP_EXCL); | ||
2458 | if (error) | ||
2459 | goto out_dput; | ||
2460 | } | ||
2461 | out_no_open: | ||
2462 | path->dentry = dentry; | ||
2463 | path->mnt = nd->path.mnt; | ||
2464 | return 1; | ||
2465 | |||
2466 | out_dput: | ||
2467 | dput(dentry); | ||
2468 | return error; | ||
2469 | } | ||
2470 | |||
2471 | /* | ||
2472 | * Handle the last step of open() | ||
2473 | */ | ||
2474 | static int do_last(struct nameidata *nd, struct path *path, | ||
2475 | struct file *file, const struct open_flags *op, | ||
2476 | int *opened, const char *pathname) | ||
2477 | { | ||
2478 | struct dentry *dir = nd->path.dentry; | ||
2198 | int open_flag = op->open_flag; | 2479 | int open_flag = op->open_flag; |
2199 | int will_truncate = open_flag & O_TRUNC; | 2480 | bool will_truncate = (open_flag & O_TRUNC) != 0; |
2200 | int want_write = 0; | 2481 | bool want_write = false; |
2201 | int acc_mode = op->acc_mode; | 2482 | int acc_mode = op->acc_mode; |
2202 | struct file *filp; | ||
2203 | struct inode *inode; | 2483 | struct inode *inode; |
2204 | int symlink_ok = 0; | 2484 | bool symlink_ok = false; |
2205 | struct path save_parent = { .dentry = NULL, .mnt = NULL }; | 2485 | struct path save_parent = { .dentry = NULL, .mnt = NULL }; |
2206 | bool retried = false; | 2486 | bool retried = false; |
2207 | int error; | 2487 | int error; |
@@ -2214,112 +2494,99 @@ static struct file *do_last(struct nameidata *nd, struct path *path, | |||
2214 | case LAST_DOT: | 2494 | case LAST_DOT: |
2215 | error = handle_dots(nd, nd->last_type); | 2495 | error = handle_dots(nd, nd->last_type); |
2216 | if (error) | 2496 | if (error) |
2217 | return ERR_PTR(error); | 2497 | return error; |
2218 | /* fallthrough */ | 2498 | /* fallthrough */ |
2219 | case LAST_ROOT: | 2499 | case LAST_ROOT: |
2220 | error = complete_walk(nd); | 2500 | error = complete_walk(nd); |
2221 | if (error) | 2501 | if (error) |
2222 | return ERR_PTR(error); | 2502 | return error; |
2223 | audit_inode(pathname, nd->path.dentry); | 2503 | audit_inode(pathname, nd->path.dentry); |
2224 | if (open_flag & O_CREAT) { | 2504 | if (open_flag & O_CREAT) { |
2225 | error = -EISDIR; | 2505 | error = -EISDIR; |
2226 | goto exit; | 2506 | goto out; |
2227 | } | 2507 | } |
2228 | goto ok; | 2508 | goto finish_open; |
2229 | case LAST_BIND: | 2509 | case LAST_BIND: |
2230 | error = complete_walk(nd); | 2510 | error = complete_walk(nd); |
2231 | if (error) | 2511 | if (error) |
2232 | return ERR_PTR(error); | 2512 | return error; |
2233 | audit_inode(pathname, dir); | 2513 | audit_inode(pathname, dir); |
2234 | goto ok; | 2514 | goto finish_open; |
2235 | } | 2515 | } |
2236 | 2516 | ||
2237 | if (!(open_flag & O_CREAT)) { | 2517 | if (!(open_flag & O_CREAT)) { |
2238 | if (nd->last.name[nd->last.len]) | 2518 | if (nd->last.name[nd->last.len]) |
2239 | nd->flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY; | 2519 | nd->flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY; |
2240 | if (open_flag & O_PATH && !(nd->flags & LOOKUP_FOLLOW)) | 2520 | if (open_flag & O_PATH && !(nd->flags & LOOKUP_FOLLOW)) |
2241 | symlink_ok = 1; | 2521 | symlink_ok = true; |
2242 | /* we _can_ be in RCU mode here */ | 2522 | /* we _can_ be in RCU mode here */ |
2243 | error = lookup_fast(nd, &nd->last, path, &inode); | 2523 | error = lookup_fast(nd, &nd->last, path, &inode); |
2244 | if (unlikely(error)) { | 2524 | if (likely(!error)) |
2245 | if (error < 0) | 2525 | goto finish_lookup; |
2246 | goto exit; | ||
2247 | 2526 | ||
2248 | error = lookup_slow(nd, &nd->last, path); | 2527 | if (error < 0) |
2249 | if (error < 0) | 2528 | goto out; |
2250 | goto exit; | ||
2251 | 2529 | ||
2252 | inode = path->dentry->d_inode; | 2530 | BUG_ON(nd->inode != dir->d_inode); |
2253 | } | 2531 | } else { |
2254 | goto finish_lookup; | 2532 | /* create side of things */ |
2255 | } | 2533 | /* |
2256 | 2534 | * This will *only* deal with leaving RCU mode - LOOKUP_JUMPED | |
2257 | /* create side of things */ | 2535 | * has been cleared when we got to the last component we are |
2258 | /* | 2536 | * about to look up |
2259 | * This will *only* deal with leaving RCU mode - LOOKUP_JUMPED has been | 2537 | */ |
2260 | * cleared when we got to the last component we are about to look up | 2538 | error = complete_walk(nd); |
2261 | */ | 2539 | if (error) |
2262 | error = complete_walk(nd); | 2540 | return error; |
2263 | if (error) | ||
2264 | return ERR_PTR(error); | ||
2265 | 2541 | ||
2266 | audit_inode(pathname, dir); | 2542 | audit_inode(pathname, dir); |
2267 | error = -EISDIR; | 2543 | error = -EISDIR; |
2268 | /* trailing slashes? */ | 2544 | /* trailing slashes? */ |
2269 | if (nd->last.name[nd->last.len]) | 2545 | if (nd->last.name[nd->last.len]) |
2270 | goto exit; | 2546 | goto out; |
2547 | } | ||
2271 | 2548 | ||
2272 | retry_lookup: | 2549 | retry_lookup: |
2273 | mutex_lock(&dir->d_inode->i_mutex); | 2550 | mutex_lock(&dir->d_inode->i_mutex); |
2551 | error = lookup_open(nd, path, file, op, &want_write, opened); | ||
2552 | mutex_unlock(&dir->d_inode->i_mutex); | ||
2274 | 2553 | ||
2275 | dentry = lookup_hash(nd); | 2554 | if (error <= 0) { |
2276 | error = PTR_ERR(dentry); | 2555 | if (error) |
2277 | if (IS_ERR(dentry)) { | 2556 | goto out; |
2278 | mutex_unlock(&dir->d_inode->i_mutex); | ||
2279 | goto exit; | ||
2280 | } | ||
2281 | 2557 | ||
2282 | path->dentry = dentry; | 2558 | if ((*opened & FILE_CREATED) || |
2283 | path->mnt = nd->path.mnt; | 2559 | !S_ISREG(file->f_path.dentry->d_inode->i_mode)) |
2560 | will_truncate = false; | ||
2284 | 2561 | ||
2285 | /* Negative dentry, just create the file */ | 2562 | audit_inode(pathname, file->f_path.dentry); |
2286 | if (!dentry->d_inode) { | 2563 | goto opened; |
2287 | umode_t mode = op->mode; | 2564 | } |
2288 | if (!IS_POSIXACL(dir->d_inode)) | 2565 | |
2289 | mode &= ~current_umask(); | 2566 | if (*opened & FILE_CREATED) { |
2290 | /* | ||
2291 | * This write is needed to ensure that a | ||
2292 | * rw->ro transition does not occur between | ||
2293 | * the time when the file is created and when | ||
2294 | * a permanent write count is taken through | ||
2295 | * the 'struct file' in nameidata_to_filp(). | ||
2296 | */ | ||
2297 | error = mnt_want_write(nd->path.mnt); | ||
2298 | if (error) | ||
2299 | goto exit_mutex_unlock; | ||
2300 | want_write = 1; | ||
2301 | /* Don't check for write permission, don't truncate */ | 2567 | /* Don't check for write permission, don't truncate */ |
2302 | open_flag &= ~O_TRUNC; | 2568 | open_flag &= ~O_TRUNC; |
2303 | will_truncate = 0; | 2569 | will_truncate = false; |
2304 | acc_mode = MAY_OPEN; | 2570 | acc_mode = MAY_OPEN; |
2305 | error = security_path_mknod(&nd->path, dentry, mode, 0); | 2571 | path_to_nameidata(path, nd); |
2306 | if (error) | 2572 | goto finish_open_created; |
2307 | goto exit_mutex_unlock; | ||
2308 | error = vfs_create(dir->d_inode, dentry, mode, nd); | ||
2309 | if (error) | ||
2310 | goto exit_mutex_unlock; | ||
2311 | mutex_unlock(&dir->d_inode->i_mutex); | ||
2312 | dput(nd->path.dentry); | ||
2313 | nd->path.dentry = dentry; | ||
2314 | goto common; | ||
2315 | } | 2573 | } |
2316 | 2574 | ||
2317 | /* | 2575 | /* |
2318 | * It already exists. | 2576 | * It already exists. |
2319 | */ | 2577 | */ |
2320 | mutex_unlock(&dir->d_inode->i_mutex); | ||
2321 | audit_inode(pathname, path->dentry); | 2578 | audit_inode(pathname, path->dentry); |
2322 | 2579 | ||
2580 | /* | ||
2581 | * If atomic_open() acquired write access it is dropped now due to | ||
2582 | * possible mount and symlink following (this might be optimized away if | ||
2583 | * necessary...) | ||
2584 | */ | ||
2585 | if (want_write) { | ||
2586 | mnt_drop_write(nd->path.mnt); | ||
2587 | want_write = false; | ||
2588 | } | ||
2589 | |||
2323 | error = -EEXIST; | 2590 | error = -EEXIST; |
2324 | if (open_flag & O_EXCL) | 2591 | if (open_flag & O_EXCL) |
2325 | goto exit_dput; | 2592 | goto exit_dput; |
@@ -2338,18 +2605,18 @@ finish_lookup: | |||
2338 | error = -ENOENT; | 2605 | error = -ENOENT; |
2339 | if (!inode) { | 2606 | if (!inode) { |
2340 | path_to_nameidata(path, nd); | 2607 | path_to_nameidata(path, nd); |
2341 | goto exit; | 2608 | goto out; |
2342 | } | 2609 | } |
2343 | 2610 | ||
2344 | if (should_follow_link(inode, !symlink_ok)) { | 2611 | if (should_follow_link(inode, !symlink_ok)) { |
2345 | if (nd->flags & LOOKUP_RCU) { | 2612 | if (nd->flags & LOOKUP_RCU) { |
2346 | if (unlikely(unlazy_walk(nd, path->dentry))) { | 2613 | if (unlikely(unlazy_walk(nd, path->dentry))) { |
2347 | error = -ECHILD; | 2614 | error = -ECHILD; |
2348 | goto exit; | 2615 | goto out; |
2349 | } | 2616 | } |
2350 | } | 2617 | } |
2351 | BUG_ON(inode != path->dentry->d_inode); | 2618 | BUG_ON(inode != path->dentry->d_inode); |
2352 | return NULL; | 2619 | return 1; |
2353 | } | 2620 | } |
2354 | 2621 | ||
2355 | if ((nd->flags & LOOKUP_RCU) || nd->path.mnt != path->mnt) { | 2622 | if ((nd->flags & LOOKUP_RCU) || nd->path.mnt != path->mnt) { |
@@ -2365,119 +2632,122 @@ finish_lookup: | |||
2365 | error = complete_walk(nd); | 2632 | error = complete_walk(nd); |
2366 | if (error) { | 2633 | if (error) { |
2367 | path_put(&save_parent); | 2634 | path_put(&save_parent); |
2368 | return ERR_PTR(error); | 2635 | return error; |
2369 | } | 2636 | } |
2370 | error = -EISDIR; | 2637 | error = -EISDIR; |
2371 | if ((open_flag & O_CREAT) && S_ISDIR(nd->inode->i_mode)) | 2638 | if ((open_flag & O_CREAT) && S_ISDIR(nd->inode->i_mode)) |
2372 | goto exit; | 2639 | goto out; |
2373 | error = -ENOTDIR; | 2640 | error = -ENOTDIR; |
2374 | if ((nd->flags & LOOKUP_DIRECTORY) && !nd->inode->i_op->lookup) | 2641 | if ((nd->flags & LOOKUP_DIRECTORY) && !nd->inode->i_op->lookup) |
2375 | goto exit; | 2642 | goto out; |
2376 | audit_inode(pathname, nd->path.dentry); | 2643 | audit_inode(pathname, nd->path.dentry); |
2377 | ok: | 2644 | finish_open: |
2378 | if (!S_ISREG(nd->inode->i_mode)) | 2645 | if (!S_ISREG(nd->inode->i_mode)) |
2379 | will_truncate = 0; | 2646 | will_truncate = false; |
2380 | 2647 | ||
2381 | if (will_truncate) { | 2648 | if (will_truncate) { |
2382 | error = mnt_want_write(nd->path.mnt); | 2649 | error = mnt_want_write(nd->path.mnt); |
2383 | if (error) | 2650 | if (error) |
2384 | goto exit; | 2651 | goto out; |
2385 | want_write = 1; | 2652 | want_write = true; |
2386 | } | 2653 | } |
2387 | common: | 2654 | finish_open_created: |
2388 | error = may_open(&nd->path, acc_mode, open_flag); | 2655 | error = may_open(&nd->path, acc_mode, open_flag); |
2389 | if (error) | 2656 | if (error) |
2390 | goto exit; | 2657 | goto out; |
2391 | filp = nameidata_to_filp(nd); | 2658 | file->f_path.mnt = nd->path.mnt; |
2392 | if (filp == ERR_PTR(-EOPENSTALE) && save_parent.dentry && !retried) { | 2659 | error = finish_open(file, nd->path.dentry, NULL, opened); |
2393 | BUG_ON(save_parent.dentry != dir); | 2660 | if (error) { |
2394 | path_put(&nd->path); | 2661 | if (error == -EOPENSTALE) |
2395 | nd->path = save_parent; | 2662 | goto stale_open; |
2396 | nd->inode = dir->d_inode; | 2663 | goto out; |
2397 | save_parent.mnt = NULL; | ||
2398 | save_parent.dentry = NULL; | ||
2399 | if (want_write) { | ||
2400 | mnt_drop_write(nd->path.mnt); | ||
2401 | want_write = 0; | ||
2402 | } | ||
2403 | retried = true; | ||
2404 | goto retry_lookup; | ||
2405 | } | ||
2406 | if (!IS_ERR(filp)) { | ||
2407 | error = ima_file_check(filp, op->acc_mode); | ||
2408 | if (error) { | ||
2409 | fput(filp); | ||
2410 | filp = ERR_PTR(error); | ||
2411 | } | ||
2412 | } | 2664 | } |
2413 | if (!IS_ERR(filp)) { | 2665 | opened: |
2414 | if (will_truncate) { | 2666 | error = open_check_o_direct(file); |
2415 | error = handle_truncate(filp); | 2667 | if (error) |
2416 | if (error) { | 2668 | goto exit_fput; |
2417 | fput(filp); | 2669 | error = ima_file_check(file, op->acc_mode); |
2418 | filp = ERR_PTR(error); | 2670 | if (error) |
2419 | } | 2671 | goto exit_fput; |
2420 | } | 2672 | |
2673 | if (will_truncate) { | ||
2674 | error = handle_truncate(file); | ||
2675 | if (error) | ||
2676 | goto exit_fput; | ||
2421 | } | 2677 | } |
2422 | out: | 2678 | out: |
2423 | if (want_write) | 2679 | if (want_write) |
2424 | mnt_drop_write(nd->path.mnt); | 2680 | mnt_drop_write(nd->path.mnt); |
2425 | path_put(&save_parent); | 2681 | path_put(&save_parent); |
2426 | terminate_walk(nd); | 2682 | terminate_walk(nd); |
2427 | return filp; | 2683 | return error; |
2428 | 2684 | ||
2429 | exit_mutex_unlock: | ||
2430 | mutex_unlock(&dir->d_inode->i_mutex); | ||
2431 | exit_dput: | 2685 | exit_dput: |
2432 | path_put_conditional(path, nd); | 2686 | path_put_conditional(path, nd); |
2433 | exit: | ||
2434 | filp = ERR_PTR(error); | ||
2435 | goto out; | 2687 | goto out; |
2688 | exit_fput: | ||
2689 | fput(file); | ||
2690 | goto out; | ||
2691 | |||
2692 | stale_open: | ||
2693 | /* If no saved parent or already retried then can't retry */ | ||
2694 | if (!save_parent.dentry || retried) | ||
2695 | goto out; | ||
2696 | |||
2697 | BUG_ON(save_parent.dentry != dir); | ||
2698 | path_put(&nd->path); | ||
2699 | nd->path = save_parent; | ||
2700 | nd->inode = dir->d_inode; | ||
2701 | save_parent.mnt = NULL; | ||
2702 | save_parent.dentry = NULL; | ||
2703 | if (want_write) { | ||
2704 | mnt_drop_write(nd->path.mnt); | ||
2705 | want_write = false; | ||
2706 | } | ||
2707 | retried = true; | ||
2708 | goto retry_lookup; | ||
2436 | } | 2709 | } |
2437 | 2710 | ||
2438 | static struct file *path_openat(int dfd, const char *pathname, | 2711 | static struct file *path_openat(int dfd, const char *pathname, |
2439 | struct nameidata *nd, const struct open_flags *op, int flags) | 2712 | struct nameidata *nd, const struct open_flags *op, int flags) |
2440 | { | 2713 | { |
2441 | struct file *base = NULL; | 2714 | struct file *base = NULL; |
2442 | struct file *filp; | 2715 | struct file *file; |
2443 | struct path path; | 2716 | struct path path; |
2717 | int opened = 0; | ||
2444 | int error; | 2718 | int error; |
2445 | 2719 | ||
2446 | filp = get_empty_filp(); | 2720 | file = get_empty_filp(); |
2447 | if (!filp) | 2721 | if (!file) |
2448 | return ERR_PTR(-ENFILE); | 2722 | return ERR_PTR(-ENFILE); |
2449 | 2723 | ||
2450 | filp->f_flags = op->open_flag; | 2724 | file->f_flags = op->open_flag; |
2451 | nd->intent.open.file = filp; | ||
2452 | nd->intent.open.flags = open_to_namei_flags(op->open_flag); | ||
2453 | nd->intent.open.create_mode = op->mode; | ||
2454 | 2725 | ||
2455 | error = path_init(dfd, pathname, flags | LOOKUP_PARENT, nd, &base); | 2726 | error = path_init(dfd, pathname, flags | LOOKUP_PARENT, nd, &base); |
2456 | if (unlikely(error)) | 2727 | if (unlikely(error)) |
2457 | goto out_filp; | 2728 | goto out; |
2458 | 2729 | ||
2459 | current->total_link_count = 0; | 2730 | current->total_link_count = 0; |
2460 | error = link_path_walk(pathname, nd); | 2731 | error = link_path_walk(pathname, nd); |
2461 | if (unlikely(error)) | 2732 | if (unlikely(error)) |
2462 | goto out_filp; | 2733 | goto out; |
2463 | 2734 | ||
2464 | filp = do_last(nd, &path, op, pathname); | 2735 | error = do_last(nd, &path, file, op, &opened, pathname); |
2465 | while (unlikely(!filp)) { /* trailing symlink */ | 2736 | while (unlikely(error > 0)) { /* trailing symlink */ |
2466 | struct path link = path; | 2737 | struct path link = path; |
2467 | void *cookie; | 2738 | void *cookie; |
2468 | if (!(nd->flags & LOOKUP_FOLLOW)) { | 2739 | if (!(nd->flags & LOOKUP_FOLLOW)) { |
2469 | path_put_conditional(&path, nd); | 2740 | path_put_conditional(&path, nd); |
2470 | path_put(&nd->path); | 2741 | path_put(&nd->path); |
2471 | filp = ERR_PTR(-ELOOP); | 2742 | error = -ELOOP; |
2472 | break; | 2743 | break; |
2473 | } | 2744 | } |
2474 | nd->flags |= LOOKUP_PARENT; | 2745 | nd->flags |= LOOKUP_PARENT; |
2475 | nd->flags &= ~(LOOKUP_OPEN|LOOKUP_CREATE|LOOKUP_EXCL); | 2746 | nd->flags &= ~(LOOKUP_OPEN|LOOKUP_CREATE|LOOKUP_EXCL); |
2476 | error = follow_link(&link, nd, &cookie); | 2747 | error = follow_link(&link, nd, &cookie); |
2477 | if (unlikely(error)) | 2748 | if (unlikely(error)) |
2478 | filp = ERR_PTR(error); | 2749 | break; |
2479 | else | 2750 | error = do_last(nd, &path, file, op, &opened, pathname); |
2480 | filp = do_last(nd, &path, op, pathname); | ||
2481 | put_link(nd, &link, cookie); | 2751 | put_link(nd, &link, cookie); |
2482 | } | 2752 | } |
2483 | out: | 2753 | out: |
@@ -2485,18 +2755,20 @@ out: | |||
2485 | path_put(&nd->root); | 2755 | path_put(&nd->root); |
2486 | if (base) | 2756 | if (base) |
2487 | fput(base); | 2757 | fput(base); |
2488 | release_open_intent(nd); | 2758 | if (!(opened & FILE_OPENED)) { |
2489 | if (filp == ERR_PTR(-EOPENSTALE)) { | 2759 | BUG_ON(!error); |
2490 | if (flags & LOOKUP_RCU) | 2760 | put_filp(file); |
2491 | filp = ERR_PTR(-ECHILD); | ||
2492 | else | ||
2493 | filp = ERR_PTR(-ESTALE); | ||
2494 | } | 2761 | } |
2495 | return filp; | 2762 | if (unlikely(error)) { |
2496 | 2763 | if (error == -EOPENSTALE) { | |
2497 | out_filp: | 2764 | if (flags & LOOKUP_RCU) |
2498 | filp = ERR_PTR(error); | 2765 | error = -ECHILD; |
2499 | goto out; | 2766 | else |
2767 | error = -ESTALE; | ||
2768 | } | ||
2769 | file = ERR_PTR(error); | ||
2770 | } | ||
2771 | return file; | ||
2500 | } | 2772 | } |
2501 | 2773 | ||
2502 | struct file *do_filp_open(int dfd, const char *pathname, | 2774 | struct file *do_filp_open(int dfd, const char *pathname, |
@@ -2551,7 +2823,6 @@ struct dentry *kern_path_create(int dfd, const char *pathname, struct path *path | |||
2551 | goto out; | 2823 | goto out; |
2552 | nd.flags &= ~LOOKUP_PARENT; | 2824 | nd.flags &= ~LOOKUP_PARENT; |
2553 | nd.flags |= LOOKUP_CREATE | LOOKUP_EXCL; | 2825 | nd.flags |= LOOKUP_CREATE | LOOKUP_EXCL; |
2554 | nd.intent.open.flags = O_EXCL; | ||
2555 | 2826 | ||
2556 | /* | 2827 | /* |
2557 | * Do the final lookup. | 2828 | * Do the final lookup. |
@@ -2670,7 +2941,7 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, umode_t, mode, | |||
2670 | goto out_drop_write; | 2941 | goto out_drop_write; |
2671 | switch (mode & S_IFMT) { | 2942 | switch (mode & S_IFMT) { |
2672 | case 0: case S_IFREG: | 2943 | case 0: case S_IFREG: |
2673 | error = vfs_create(path.dentry->d_inode,dentry,mode,NULL); | 2944 | error = vfs_create(path.dentry->d_inode,dentry,mode,true); |
2674 | break; | 2945 | break; |
2675 | case S_IFCHR: case S_IFBLK: | 2946 | case S_IFCHR: case S_IFBLK: |
2676 | error = vfs_mknod(path.dentry->d_inode,dentry,mode, | 2947 | error = vfs_mknod(path.dentry->d_inode,dentry,mode, |
diff --git a/fs/namespace.c b/fs/namespace.c index 1e4a5fe3d7b7..c53d3381b0d0 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -515,8 +515,20 @@ struct mount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry, | |||
515 | } | 515 | } |
516 | 516 | ||
517 | /* | 517 | /* |
518 | * lookup_mnt increments the ref count before returning | 518 | * lookup_mnt - Return the first child mount mounted at path |
519 | * the vfsmount struct. | 519 | * |
520 | * "First" means first mounted chronologically. If you create the | ||
521 | * following mounts: | ||
522 | * | ||
523 | * mount /dev/sda1 /mnt | ||
524 | * mount /dev/sda2 /mnt | ||
525 | * mount /dev/sda3 /mnt | ||
526 | * | ||
527 | * Then lookup_mnt() on the base /mnt dentry in the root mount will | ||
528 | * return successively the root dentry and vfsmount of /dev/sda1, then | ||
529 | * /dev/sda2, then /dev/sda3, then NULL. | ||
530 | * | ||
531 | * lookup_mnt takes a reference to the found vfsmount. | ||
520 | */ | 532 | */ |
521 | struct vfsmount *lookup_mnt(struct path *path) | 533 | struct vfsmount *lookup_mnt(struct path *path) |
522 | { | 534 | { |
@@ -621,21 +633,6 @@ static void attach_mnt(struct mount *mnt, struct path *path) | |||
621 | list_add_tail(&mnt->mnt_child, &real_mount(path->mnt)->mnt_mounts); | 633 | list_add_tail(&mnt->mnt_child, &real_mount(path->mnt)->mnt_mounts); |
622 | } | 634 | } |
623 | 635 | ||
624 | static inline void __mnt_make_longterm(struct mount *mnt) | ||
625 | { | ||
626 | #ifdef CONFIG_SMP | ||
627 | atomic_inc(&mnt->mnt_longterm); | ||
628 | #endif | ||
629 | } | ||
630 | |||
631 | /* needs vfsmount lock for write */ | ||
632 | static inline void __mnt_make_shortterm(struct mount *mnt) | ||
633 | { | ||
634 | #ifdef CONFIG_SMP | ||
635 | atomic_dec(&mnt->mnt_longterm); | ||
636 | #endif | ||
637 | } | ||
638 | |||
639 | /* | 636 | /* |
640 | * vfsmount lock must be held for write | 637 | * vfsmount lock must be held for write |
641 | */ | 638 | */ |
@@ -649,10 +646,8 @@ static void commit_tree(struct mount *mnt) | |||
649 | BUG_ON(parent == mnt); | 646 | BUG_ON(parent == mnt); |
650 | 647 | ||
651 | list_add_tail(&head, &mnt->mnt_list); | 648 | list_add_tail(&head, &mnt->mnt_list); |
652 | list_for_each_entry(m, &head, mnt_list) { | 649 | list_for_each_entry(m, &head, mnt_list) |
653 | m->mnt_ns = n; | 650 | m->mnt_ns = n; |
654 | __mnt_make_longterm(m); | ||
655 | } | ||
656 | 651 | ||
657 | list_splice(&head, n->list.prev); | 652 | list_splice(&head, n->list.prev); |
658 | 653 | ||
@@ -725,56 +720,60 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root, | |||
725 | int flag) | 720 | int flag) |
726 | { | 721 | { |
727 | struct super_block *sb = old->mnt.mnt_sb; | 722 | struct super_block *sb = old->mnt.mnt_sb; |
728 | struct mount *mnt = alloc_vfsmnt(old->mnt_devname); | 723 | struct mount *mnt; |
724 | int err; | ||
729 | 725 | ||
730 | if (mnt) { | 726 | mnt = alloc_vfsmnt(old->mnt_devname); |
731 | if (flag & (CL_SLAVE | CL_PRIVATE)) | 727 | if (!mnt) |
732 | mnt->mnt_group_id = 0; /* not a peer of original */ | 728 | return ERR_PTR(-ENOMEM); |
733 | else | ||
734 | mnt->mnt_group_id = old->mnt_group_id; | ||
735 | |||
736 | if ((flag & CL_MAKE_SHARED) && !mnt->mnt_group_id) { | ||
737 | int err = mnt_alloc_group_id(mnt); | ||
738 | if (err) | ||
739 | goto out_free; | ||
740 | } | ||
741 | 729 | ||
742 | mnt->mnt.mnt_flags = old->mnt.mnt_flags & ~MNT_WRITE_HOLD; | 730 | if (flag & (CL_SLAVE | CL_PRIVATE)) |
743 | atomic_inc(&sb->s_active); | 731 | mnt->mnt_group_id = 0; /* not a peer of original */ |
744 | mnt->mnt.mnt_sb = sb; | 732 | else |
745 | mnt->mnt.mnt_root = dget(root); | 733 | mnt->mnt_group_id = old->mnt_group_id; |
746 | mnt->mnt_mountpoint = mnt->mnt.mnt_root; | ||
747 | mnt->mnt_parent = mnt; | ||
748 | br_write_lock(&vfsmount_lock); | ||
749 | list_add_tail(&mnt->mnt_instance, &sb->s_mounts); | ||
750 | br_write_unlock(&vfsmount_lock); | ||
751 | 734 | ||
752 | if (flag & CL_SLAVE) { | 735 | if ((flag & CL_MAKE_SHARED) && !mnt->mnt_group_id) { |
753 | list_add(&mnt->mnt_slave, &old->mnt_slave_list); | 736 | err = mnt_alloc_group_id(mnt); |
754 | mnt->mnt_master = old; | 737 | if (err) |
755 | CLEAR_MNT_SHARED(mnt); | 738 | goto out_free; |
756 | } else if (!(flag & CL_PRIVATE)) { | ||
757 | if ((flag & CL_MAKE_SHARED) || IS_MNT_SHARED(old)) | ||
758 | list_add(&mnt->mnt_share, &old->mnt_share); | ||
759 | if (IS_MNT_SLAVE(old)) | ||
760 | list_add(&mnt->mnt_slave, &old->mnt_slave); | ||
761 | mnt->mnt_master = old->mnt_master; | ||
762 | } | ||
763 | if (flag & CL_MAKE_SHARED) | ||
764 | set_mnt_shared(mnt); | ||
765 | |||
766 | /* stick the duplicate mount on the same expiry list | ||
767 | * as the original if that was on one */ | ||
768 | if (flag & CL_EXPIRE) { | ||
769 | if (!list_empty(&old->mnt_expire)) | ||
770 | list_add(&mnt->mnt_expire, &old->mnt_expire); | ||
771 | } | ||
772 | } | 739 | } |
740 | |||
741 | mnt->mnt.mnt_flags = old->mnt.mnt_flags & ~MNT_WRITE_HOLD; | ||
742 | atomic_inc(&sb->s_active); | ||
743 | mnt->mnt.mnt_sb = sb; | ||
744 | mnt->mnt.mnt_root = dget(root); | ||
745 | mnt->mnt_mountpoint = mnt->mnt.mnt_root; | ||
746 | mnt->mnt_parent = mnt; | ||
747 | br_write_lock(&vfsmount_lock); | ||
748 | list_add_tail(&mnt->mnt_instance, &sb->s_mounts); | ||
749 | br_write_unlock(&vfsmount_lock); | ||
750 | |||
751 | if (flag & CL_SLAVE) { | ||
752 | list_add(&mnt->mnt_slave, &old->mnt_slave_list); | ||
753 | mnt->mnt_master = old; | ||
754 | CLEAR_MNT_SHARED(mnt); | ||
755 | } else if (!(flag & CL_PRIVATE)) { | ||
756 | if ((flag & CL_MAKE_SHARED) || IS_MNT_SHARED(old)) | ||
757 | list_add(&mnt->mnt_share, &old->mnt_share); | ||
758 | if (IS_MNT_SLAVE(old)) | ||
759 | list_add(&mnt->mnt_slave, &old->mnt_slave); | ||
760 | mnt->mnt_master = old->mnt_master; | ||
761 | } | ||
762 | if (flag & CL_MAKE_SHARED) | ||
763 | set_mnt_shared(mnt); | ||
764 | |||
765 | /* stick the duplicate mount on the same expiry list | ||
766 | * as the original if that was on one */ | ||
767 | if (flag & CL_EXPIRE) { | ||
768 | if (!list_empty(&old->mnt_expire)) | ||
769 | list_add(&mnt->mnt_expire, &old->mnt_expire); | ||
770 | } | ||
771 | |||
773 | return mnt; | 772 | return mnt; |
774 | 773 | ||
775 | out_free: | 774 | out_free: |
776 | free_vfsmnt(mnt); | 775 | free_vfsmnt(mnt); |
777 | return NULL; | 776 | return ERR_PTR(err); |
778 | } | 777 | } |
779 | 778 | ||
780 | static inline void mntfree(struct mount *mnt) | 779 | static inline void mntfree(struct mount *mnt) |
@@ -804,7 +803,8 @@ static void mntput_no_expire(struct mount *mnt) | |||
804 | put_again: | 803 | put_again: |
805 | #ifdef CONFIG_SMP | 804 | #ifdef CONFIG_SMP |
806 | br_read_lock(&vfsmount_lock); | 805 | br_read_lock(&vfsmount_lock); |
807 | if (likely(atomic_read(&mnt->mnt_longterm))) { | 806 | if (likely(mnt->mnt_ns)) { |
807 | /* shouldn't be the last one */ | ||
808 | mnt_add_count(mnt, -1); | 808 | mnt_add_count(mnt, -1); |
809 | br_read_unlock(&vfsmount_lock); | 809 | br_read_unlock(&vfsmount_lock); |
810 | return; | 810 | return; |
@@ -939,7 +939,7 @@ EXPORT_SYMBOL(replace_mount_options); | |||
939 | /* iterator; we want it to have access to namespace_sem, thus here... */ | 939 | /* iterator; we want it to have access to namespace_sem, thus here... */ |
940 | static void *m_start(struct seq_file *m, loff_t *pos) | 940 | static void *m_start(struct seq_file *m, loff_t *pos) |
941 | { | 941 | { |
942 | struct proc_mounts *p = container_of(m, struct proc_mounts, m); | 942 | struct proc_mounts *p = proc_mounts(m); |
943 | 943 | ||
944 | down_read(&namespace_sem); | 944 | down_read(&namespace_sem); |
945 | return seq_list_start(&p->ns->list, *pos); | 945 | return seq_list_start(&p->ns->list, *pos); |
@@ -947,7 +947,7 @@ static void *m_start(struct seq_file *m, loff_t *pos) | |||
947 | 947 | ||
948 | static void *m_next(struct seq_file *m, void *v, loff_t *pos) | 948 | static void *m_next(struct seq_file *m, void *v, loff_t *pos) |
949 | { | 949 | { |
950 | struct proc_mounts *p = container_of(m, struct proc_mounts, m); | 950 | struct proc_mounts *p = proc_mounts(m); |
951 | 951 | ||
952 | return seq_list_next(v, &p->ns->list, pos); | 952 | return seq_list_next(v, &p->ns->list, pos); |
953 | } | 953 | } |
@@ -959,7 +959,7 @@ static void m_stop(struct seq_file *m, void *v) | |||
959 | 959 | ||
960 | static int m_show(struct seq_file *m, void *v) | 960 | static int m_show(struct seq_file *m, void *v) |
961 | { | 961 | { |
962 | struct proc_mounts *p = container_of(m, struct proc_mounts, m); | 962 | struct proc_mounts *p = proc_mounts(m); |
963 | struct mount *r = list_entry(v, struct mount, mnt_list); | 963 | struct mount *r = list_entry(v, struct mount, mnt_list); |
964 | return p->show(m, &r->mnt); | 964 | return p->show(m, &r->mnt); |
965 | } | 965 | } |
@@ -1074,8 +1074,6 @@ void umount_tree(struct mount *mnt, int propagate, struct list_head *kill) | |||
1074 | list_del_init(&p->mnt_expire); | 1074 | list_del_init(&p->mnt_expire); |
1075 | list_del_init(&p->mnt_list); | 1075 | list_del_init(&p->mnt_list); |
1076 | __touch_mnt_namespace(p->mnt_ns); | 1076 | __touch_mnt_namespace(p->mnt_ns); |
1077 | if (p->mnt_ns) | ||
1078 | __mnt_make_shortterm(p); | ||
1079 | p->mnt_ns = NULL; | 1077 | p->mnt_ns = NULL; |
1080 | list_del_init(&p->mnt_child); | 1078 | list_del_init(&p->mnt_child); |
1081 | if (mnt_has_parent(p)) { | 1079 | if (mnt_has_parent(p)) { |
@@ -1260,11 +1258,12 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry, | |||
1260 | struct path path; | 1258 | struct path path; |
1261 | 1259 | ||
1262 | if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(mnt)) | 1260 | if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(mnt)) |
1263 | return NULL; | 1261 | return ERR_PTR(-EINVAL); |
1264 | 1262 | ||
1265 | res = q = clone_mnt(mnt, dentry, flag); | 1263 | res = q = clone_mnt(mnt, dentry, flag); |
1266 | if (!q) | 1264 | if (IS_ERR(q)) |
1267 | goto Enomem; | 1265 | return q; |
1266 | |||
1268 | q->mnt_mountpoint = mnt->mnt_mountpoint; | 1267 | q->mnt_mountpoint = mnt->mnt_mountpoint; |
1269 | 1268 | ||
1270 | p = mnt; | 1269 | p = mnt; |
@@ -1286,8 +1285,8 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry, | |||
1286 | path.mnt = &q->mnt; | 1285 | path.mnt = &q->mnt; |
1287 | path.dentry = p->mnt_mountpoint; | 1286 | path.dentry = p->mnt_mountpoint; |
1288 | q = clone_mnt(p, p->mnt.mnt_root, flag); | 1287 | q = clone_mnt(p, p->mnt.mnt_root, flag); |
1289 | if (!q) | 1288 | if (IS_ERR(q)) |
1290 | goto Enomem; | 1289 | goto out; |
1291 | br_write_lock(&vfsmount_lock); | 1290 | br_write_lock(&vfsmount_lock); |
1292 | list_add_tail(&q->mnt_list, &res->mnt_list); | 1291 | list_add_tail(&q->mnt_list, &res->mnt_list); |
1293 | attach_mnt(q, &path); | 1292 | attach_mnt(q, &path); |
@@ -1295,7 +1294,7 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry, | |||
1295 | } | 1294 | } |
1296 | } | 1295 | } |
1297 | return res; | 1296 | return res; |
1298 | Enomem: | 1297 | out: |
1299 | if (res) { | 1298 | if (res) { |
1300 | LIST_HEAD(umount_list); | 1299 | LIST_HEAD(umount_list); |
1301 | br_write_lock(&vfsmount_lock); | 1300 | br_write_lock(&vfsmount_lock); |
@@ -1303,9 +1302,11 @@ Enomem: | |||
1303 | br_write_unlock(&vfsmount_lock); | 1302 | br_write_unlock(&vfsmount_lock); |
1304 | release_mounts(&umount_list); | 1303 | release_mounts(&umount_list); |
1305 | } | 1304 | } |
1306 | return NULL; | 1305 | return q; |
1307 | } | 1306 | } |
1308 | 1307 | ||
1308 | /* Caller should check returned pointer for errors */ | ||
1309 | |||
1309 | struct vfsmount *collect_mounts(struct path *path) | 1310 | struct vfsmount *collect_mounts(struct path *path) |
1310 | { | 1311 | { |
1311 | struct mount *tree; | 1312 | struct mount *tree; |
@@ -1313,7 +1314,9 @@ struct vfsmount *collect_mounts(struct path *path) | |||
1313 | tree = copy_tree(real_mount(path->mnt), path->dentry, | 1314 | tree = copy_tree(real_mount(path->mnt), path->dentry, |
1314 | CL_COPY_ALL | CL_PRIVATE); | 1315 | CL_COPY_ALL | CL_PRIVATE); |
1315 | up_write(&namespace_sem); | 1316 | up_write(&namespace_sem); |
1316 | return tree ? &tree->mnt : NULL; | 1317 | if (IS_ERR(tree)) |
1318 | return NULL; | ||
1319 | return &tree->mnt; | ||
1317 | } | 1320 | } |
1318 | 1321 | ||
1319 | void drop_collected_mounts(struct vfsmount *mnt) | 1322 | void drop_collected_mounts(struct vfsmount *mnt) |
@@ -1608,14 +1611,15 @@ static int do_loopback(struct path *path, char *old_name, | |||
1608 | if (!check_mnt(real_mount(path->mnt)) || !check_mnt(old)) | 1611 | if (!check_mnt(real_mount(path->mnt)) || !check_mnt(old)) |
1609 | goto out2; | 1612 | goto out2; |
1610 | 1613 | ||
1611 | err = -ENOMEM; | ||
1612 | if (recurse) | 1614 | if (recurse) |
1613 | mnt = copy_tree(old, old_path.dentry, 0); | 1615 | mnt = copy_tree(old, old_path.dentry, 0); |
1614 | else | 1616 | else |
1615 | mnt = clone_mnt(old, old_path.dentry, 0); | 1617 | mnt = clone_mnt(old, old_path.dentry, 0); |
1616 | 1618 | ||
1617 | if (!mnt) | 1619 | if (IS_ERR(mnt)) { |
1618 | goto out2; | 1620 | err = PTR_ERR(mnt); |
1621 | goto out; | ||
1622 | } | ||
1619 | 1623 | ||
1620 | err = graft_tree(mnt, path); | 1624 | err = graft_tree(mnt, path); |
1621 | if (err) { | 1625 | if (err) { |
@@ -2209,23 +2213,6 @@ static struct mnt_namespace *alloc_mnt_ns(void) | |||
2209 | return new_ns; | 2213 | return new_ns; |
2210 | } | 2214 | } |
2211 | 2215 | ||
2212 | void mnt_make_longterm(struct vfsmount *mnt) | ||
2213 | { | ||
2214 | __mnt_make_longterm(real_mount(mnt)); | ||
2215 | } | ||
2216 | |||
2217 | void mnt_make_shortterm(struct vfsmount *m) | ||
2218 | { | ||
2219 | #ifdef CONFIG_SMP | ||
2220 | struct mount *mnt = real_mount(m); | ||
2221 | if (atomic_add_unless(&mnt->mnt_longterm, -1, 1)) | ||
2222 | return; | ||
2223 | br_write_lock(&vfsmount_lock); | ||
2224 | atomic_dec(&mnt->mnt_longterm); | ||
2225 | br_write_unlock(&vfsmount_lock); | ||
2226 | #endif | ||
2227 | } | ||
2228 | |||
2229 | /* | 2216 | /* |
2230 | * Allocate a new namespace structure and populate it with contents | 2217 | * Allocate a new namespace structure and populate it with contents |
2231 | * copied from the namespace of the passed in task structure. | 2218 | * copied from the namespace of the passed in task structure. |
@@ -2246,10 +2233,10 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns, | |||
2246 | down_write(&namespace_sem); | 2233 | down_write(&namespace_sem); |
2247 | /* First pass: copy the tree topology */ | 2234 | /* First pass: copy the tree topology */ |
2248 | new = copy_tree(old, old->mnt.mnt_root, CL_COPY_ALL | CL_EXPIRE); | 2235 | new = copy_tree(old, old->mnt.mnt_root, CL_COPY_ALL | CL_EXPIRE); |
2249 | if (!new) { | 2236 | if (IS_ERR(new)) { |
2250 | up_write(&namespace_sem); | 2237 | up_write(&namespace_sem); |
2251 | kfree(new_ns); | 2238 | kfree(new_ns); |
2252 | return ERR_PTR(-ENOMEM); | 2239 | return ERR_CAST(new); |
2253 | } | 2240 | } |
2254 | new_ns->root = new; | 2241 | new_ns->root = new; |
2255 | br_write_lock(&vfsmount_lock); | 2242 | br_write_lock(&vfsmount_lock); |
@@ -2265,18 +2252,13 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns, | |||
2265 | q = new; | 2252 | q = new; |
2266 | while (p) { | 2253 | while (p) { |
2267 | q->mnt_ns = new_ns; | 2254 | q->mnt_ns = new_ns; |
2268 | __mnt_make_longterm(q); | ||
2269 | if (fs) { | 2255 | if (fs) { |
2270 | if (&p->mnt == fs->root.mnt) { | 2256 | if (&p->mnt == fs->root.mnt) { |
2271 | fs->root.mnt = mntget(&q->mnt); | 2257 | fs->root.mnt = mntget(&q->mnt); |
2272 | __mnt_make_longterm(q); | ||
2273 | mnt_make_shortterm(&p->mnt); | ||
2274 | rootmnt = &p->mnt; | 2258 | rootmnt = &p->mnt; |
2275 | } | 2259 | } |
2276 | if (&p->mnt == fs->pwd.mnt) { | 2260 | if (&p->mnt == fs->pwd.mnt) { |
2277 | fs->pwd.mnt = mntget(&q->mnt); | 2261 | fs->pwd.mnt = mntget(&q->mnt); |
2278 | __mnt_make_longterm(q); | ||
2279 | mnt_make_shortterm(&p->mnt); | ||
2280 | pwdmnt = &p->mnt; | 2262 | pwdmnt = &p->mnt; |
2281 | } | 2263 | } |
2282 | } | 2264 | } |
@@ -2320,7 +2302,6 @@ static struct mnt_namespace *create_mnt_ns(struct vfsmount *m) | |||
2320 | if (!IS_ERR(new_ns)) { | 2302 | if (!IS_ERR(new_ns)) { |
2321 | struct mount *mnt = real_mount(m); | 2303 | struct mount *mnt = real_mount(m); |
2322 | mnt->mnt_ns = new_ns; | 2304 | mnt->mnt_ns = new_ns; |
2323 | __mnt_make_longterm(mnt); | ||
2324 | new_ns->root = mnt; | 2305 | new_ns->root = mnt; |
2325 | list_add(&new_ns->list, &mnt->mnt_list); | 2306 | list_add(&new_ns->list, &mnt->mnt_list); |
2326 | } else { | 2307 | } else { |
@@ -2615,7 +2596,7 @@ struct vfsmount *kern_mount_data(struct file_system_type *type, void *data) | |||
2615 | * it is a longterm mount, don't release mnt until | 2596 | * it is a longterm mount, don't release mnt until |
2616 | * we unmount before file sys is unregistered | 2597 | * we unmount before file sys is unregistered |
2617 | */ | 2598 | */ |
2618 | mnt_make_longterm(mnt); | 2599 | real_mount(mnt)->mnt_ns = MNT_NS_INTERNAL; |
2619 | } | 2600 | } |
2620 | return mnt; | 2601 | return mnt; |
2621 | } | 2602 | } |
@@ -2625,7 +2606,9 @@ void kern_unmount(struct vfsmount *mnt) | |||
2625 | { | 2606 | { |
2626 | /* release long term mount so mount point can be released */ | 2607 | /* release long term mount so mount point can be released */ |
2627 | if (!IS_ERR_OR_NULL(mnt)) { | 2608 | if (!IS_ERR_OR_NULL(mnt)) { |
2628 | mnt_make_shortterm(mnt); | 2609 | br_write_lock(&vfsmount_lock); |
2610 | real_mount(mnt)->mnt_ns = NULL; | ||
2611 | br_write_unlock(&vfsmount_lock); | ||
2629 | mntput(mnt); | 2612 | mntput(mnt); |
2630 | } | 2613 | } |
2631 | } | 2614 | } |
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index aeed93a6bde0..4117e7b377bb 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c | |||
@@ -30,8 +30,8 @@ static void ncp_do_readdir(struct file *, void *, filldir_t, | |||
30 | 30 | ||
31 | static int ncp_readdir(struct file *, void *, filldir_t); | 31 | static int ncp_readdir(struct file *, void *, filldir_t); |
32 | 32 | ||
33 | static int ncp_create(struct inode *, struct dentry *, umode_t, struct nameidata *); | 33 | static int ncp_create(struct inode *, struct dentry *, umode_t, bool); |
34 | static struct dentry *ncp_lookup(struct inode *, struct dentry *, struct nameidata *); | 34 | static struct dentry *ncp_lookup(struct inode *, struct dentry *, unsigned int); |
35 | static int ncp_unlink(struct inode *, struct dentry *); | 35 | static int ncp_unlink(struct inode *, struct dentry *); |
36 | static int ncp_mkdir(struct inode *, struct dentry *, umode_t); | 36 | static int ncp_mkdir(struct inode *, struct dentry *, umode_t); |
37 | static int ncp_rmdir(struct inode *, struct dentry *); | 37 | static int ncp_rmdir(struct inode *, struct dentry *); |
@@ -72,7 +72,7 @@ const struct inode_operations ncp_dir_inode_operations = | |||
72 | /* | 72 | /* |
73 | * Dentry operations routines | 73 | * Dentry operations routines |
74 | */ | 74 | */ |
75 | static int ncp_lookup_validate(struct dentry *, struct nameidata *); | 75 | static int ncp_lookup_validate(struct dentry *, unsigned int); |
76 | static int ncp_hash_dentry(const struct dentry *, const struct inode *, | 76 | static int ncp_hash_dentry(const struct dentry *, const struct inode *, |
77 | struct qstr *); | 77 | struct qstr *); |
78 | static int ncp_compare_dentry(const struct dentry *, const struct inode *, | 78 | static int ncp_compare_dentry(const struct dentry *, const struct inode *, |
@@ -290,7 +290,7 @@ leave_me:; | |||
290 | 290 | ||
291 | 291 | ||
292 | static int | 292 | static int |
293 | ncp_lookup_validate(struct dentry *dentry, struct nameidata *nd) | 293 | ncp_lookup_validate(struct dentry *dentry, unsigned int flags) |
294 | { | 294 | { |
295 | struct ncp_server *server; | 295 | struct ncp_server *server; |
296 | struct dentry *parent; | 296 | struct dentry *parent; |
@@ -302,7 +302,7 @@ ncp_lookup_validate(struct dentry *dentry, struct nameidata *nd) | |||
302 | if (dentry == dentry->d_sb->s_root) | 302 | if (dentry == dentry->d_sb->s_root) |
303 | return 1; | 303 | return 1; |
304 | 304 | ||
305 | if (nd->flags & LOOKUP_RCU) | 305 | if (flags & LOOKUP_RCU) |
306 | return -ECHILD; | 306 | return -ECHILD; |
307 | 307 | ||
308 | parent = dget_parent(dentry); | 308 | parent = dget_parent(dentry); |
@@ -836,7 +836,7 @@ out: | |||
836 | return result; | 836 | return result; |
837 | } | 837 | } |
838 | 838 | ||
839 | static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | 839 | static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) |
840 | { | 840 | { |
841 | struct ncp_server *server = NCP_SERVER(dir); | 841 | struct ncp_server *server = NCP_SERVER(dir); |
842 | struct inode *inode = NULL; | 842 | struct inode *inode = NULL; |
@@ -980,7 +980,7 @@ out: | |||
980 | } | 980 | } |
981 | 981 | ||
982 | static int ncp_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 982 | static int ncp_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
983 | struct nameidata *nd) | 983 | bool excl) |
984 | { | 984 | { |
985 | return ncp_create_new(dir, dentry, mode, 0, 0); | 985 | return ncp_create_new(dir, dentry, mode, 0, 0); |
986 | } | 986 | } |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 68e451f59305..b7136853ca9c 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -46,8 +46,8 @@ | |||
46 | static int nfs_opendir(struct inode *, struct file *); | 46 | static int nfs_opendir(struct inode *, struct file *); |
47 | static int nfs_closedir(struct inode *, struct file *); | 47 | static int nfs_closedir(struct inode *, struct file *); |
48 | static int nfs_readdir(struct file *, void *, filldir_t); | 48 | static int nfs_readdir(struct file *, void *, filldir_t); |
49 | static struct dentry *nfs_lookup(struct inode *, struct dentry *, struct nameidata *); | 49 | static struct dentry *nfs_lookup(struct inode *, struct dentry *, unsigned int); |
50 | static int nfs_create(struct inode *, struct dentry *, umode_t, struct nameidata *); | 50 | static int nfs_create(struct inode *, struct dentry *, umode_t, bool); |
51 | static int nfs_mkdir(struct inode *, struct dentry *, umode_t); | 51 | static int nfs_mkdir(struct inode *, struct dentry *, umode_t); |
52 | static int nfs_rmdir(struct inode *, struct dentry *); | 52 | static int nfs_rmdir(struct inode *, struct dentry *); |
53 | static int nfs_unlink(struct inode *, struct dentry *); | 53 | static int nfs_unlink(struct inode *, struct dentry *); |
@@ -111,11 +111,13 @@ const struct inode_operations nfs3_dir_inode_operations = { | |||
111 | 111 | ||
112 | #ifdef CONFIG_NFS_V4 | 112 | #ifdef CONFIG_NFS_V4 |
113 | 113 | ||
114 | static struct dentry *nfs_atomic_lookup(struct inode *, struct dentry *, struct nameidata *); | 114 | static int nfs_atomic_open(struct inode *, struct dentry *, |
115 | static int nfs_open_create(struct inode *dir, struct dentry *dentry, umode_t mode, struct nameidata *nd); | 115 | struct file *, unsigned, umode_t, |
116 | int *); | ||
116 | const struct inode_operations nfs4_dir_inode_operations = { | 117 | const struct inode_operations nfs4_dir_inode_operations = { |
117 | .create = nfs_open_create, | 118 | .create = nfs_create, |
118 | .lookup = nfs_atomic_lookup, | 119 | .lookup = nfs_lookup, |
120 | .atomic_open = nfs_atomic_open, | ||
119 | .link = nfs_link, | 121 | .link = nfs_link, |
120 | .unlink = nfs_unlink, | 122 | .unlink = nfs_unlink, |
121 | .symlink = nfs_symlink, | 123 | .symlink = nfs_symlink, |
@@ -1029,27 +1031,14 @@ static int nfs_check_verifier(struct inode *dir, struct dentry *dentry) | |||
1029 | } | 1031 | } |
1030 | 1032 | ||
1031 | /* | 1033 | /* |
1032 | * Return the intent data that applies to this particular path component | ||
1033 | * | ||
1034 | * Note that the current set of intents only apply to the very last | ||
1035 | * component of the path and none of them is set before that last | ||
1036 | * component. | ||
1037 | */ | ||
1038 | static inline unsigned int nfs_lookup_check_intent(struct nameidata *nd, | ||
1039 | unsigned int mask) | ||
1040 | { | ||
1041 | return nd->flags & mask; | ||
1042 | } | ||
1043 | |||
1044 | /* | ||
1045 | * Use intent information to check whether or not we're going to do | 1034 | * Use intent information to check whether or not we're going to do |
1046 | * an O_EXCL create using this path component. | 1035 | * an O_EXCL create using this path component. |
1047 | */ | 1036 | */ |
1048 | static int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd) | 1037 | static int nfs_is_exclusive_create(struct inode *dir, unsigned int flags) |
1049 | { | 1038 | { |
1050 | if (NFS_PROTO(dir)->version == 2) | 1039 | if (NFS_PROTO(dir)->version == 2) |
1051 | return 0; | 1040 | return 0; |
1052 | return nd && nfs_lookup_check_intent(nd, LOOKUP_EXCL); | 1041 | return flags & LOOKUP_EXCL; |
1053 | } | 1042 | } |
1054 | 1043 | ||
1055 | /* | 1044 | /* |
@@ -1061,25 +1050,20 @@ static int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd) | |||
1061 | * | 1050 | * |
1062 | */ | 1051 | */ |
1063 | static inline | 1052 | static inline |
1064 | int nfs_lookup_verify_inode(struct inode *inode, struct nameidata *nd) | 1053 | int nfs_lookup_verify_inode(struct inode *inode, unsigned int flags) |
1065 | { | 1054 | { |
1066 | struct nfs_server *server = NFS_SERVER(inode); | 1055 | struct nfs_server *server = NFS_SERVER(inode); |
1067 | 1056 | ||
1068 | if (IS_AUTOMOUNT(inode)) | 1057 | if (IS_AUTOMOUNT(inode)) |
1069 | return 0; | 1058 | return 0; |
1070 | if (nd != NULL) { | 1059 | /* VFS wants an on-the-wire revalidation */ |
1071 | /* VFS wants an on-the-wire revalidation */ | 1060 | if (flags & LOOKUP_REVAL) |
1072 | if (nd->flags & LOOKUP_REVAL) | 1061 | goto out_force; |
1073 | goto out_force; | 1062 | /* This is an open(2) */ |
1074 | /* This is an open(2) */ | 1063 | if ((flags & LOOKUP_OPEN) && !(server->flags & NFS_MOUNT_NOCTO) && |
1075 | if (nfs_lookup_check_intent(nd, LOOKUP_OPEN) != 0 && | 1064 | (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) |
1076 | !(server->flags & NFS_MOUNT_NOCTO) && | 1065 | goto out_force; |
1077 | (S_ISREG(inode->i_mode) || | 1066 | return 0; |
1078 | S_ISDIR(inode->i_mode))) | ||
1079 | goto out_force; | ||
1080 | return 0; | ||
1081 | } | ||
1082 | return nfs_revalidate_inode(server, inode); | ||
1083 | out_force: | 1067 | out_force: |
1084 | return __nfs_revalidate_inode(server, inode); | 1068 | return __nfs_revalidate_inode(server, inode); |
1085 | } | 1069 | } |
@@ -1093,10 +1077,10 @@ out_force: | |||
1093 | */ | 1077 | */ |
1094 | static inline | 1078 | static inline |
1095 | int nfs_neg_need_reval(struct inode *dir, struct dentry *dentry, | 1079 | int nfs_neg_need_reval(struct inode *dir, struct dentry *dentry, |
1096 | struct nameidata *nd) | 1080 | unsigned int flags) |
1097 | { | 1081 | { |
1098 | /* Don't revalidate a negative dentry if we're creating a new file */ | 1082 | /* Don't revalidate a negative dentry if we're creating a new file */ |
1099 | if (nd != NULL && nfs_lookup_check_intent(nd, LOOKUP_CREATE) != 0) | 1083 | if (flags & LOOKUP_CREATE) |
1100 | return 0; | 1084 | return 0; |
1101 | if (NFS_SERVER(dir)->flags & NFS_MOUNT_LOOKUP_CACHE_NONEG) | 1085 | if (NFS_SERVER(dir)->flags & NFS_MOUNT_LOOKUP_CACHE_NONEG) |
1102 | return 1; | 1086 | return 1; |
@@ -1114,7 +1098,7 @@ int nfs_neg_need_reval(struct inode *dir, struct dentry *dentry, | |||
1114 | * If the parent directory is seen to have changed, we throw out the | 1098 | * If the parent directory is seen to have changed, we throw out the |
1115 | * cached dentry and do a new lookup. | 1099 | * cached dentry and do a new lookup. |
1116 | */ | 1100 | */ |
1117 | static int nfs_lookup_revalidate(struct dentry *dentry, struct nameidata *nd) | 1101 | static int nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags) |
1118 | { | 1102 | { |
1119 | struct inode *dir; | 1103 | struct inode *dir; |
1120 | struct inode *inode; | 1104 | struct inode *inode; |
@@ -1123,7 +1107,7 @@ static int nfs_lookup_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
1123 | struct nfs_fattr *fattr = NULL; | 1107 | struct nfs_fattr *fattr = NULL; |
1124 | int error; | 1108 | int error; |
1125 | 1109 | ||
1126 | if (nd->flags & LOOKUP_RCU) | 1110 | if (flags & LOOKUP_RCU) |
1127 | return -ECHILD; | 1111 | return -ECHILD; |
1128 | 1112 | ||
1129 | parent = dget_parent(dentry); | 1113 | parent = dget_parent(dentry); |
@@ -1132,7 +1116,7 @@ static int nfs_lookup_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
1132 | inode = dentry->d_inode; | 1116 | inode = dentry->d_inode; |
1133 | 1117 | ||
1134 | if (!inode) { | 1118 | if (!inode) { |
1135 | if (nfs_neg_need_reval(dir, dentry, nd)) | 1119 | if (nfs_neg_need_reval(dir, dentry, flags)) |
1136 | goto out_bad; | 1120 | goto out_bad; |
1137 | goto out_valid_noent; | 1121 | goto out_valid_noent; |
1138 | } | 1122 | } |
@@ -1148,8 +1132,8 @@ static int nfs_lookup_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
1148 | goto out_set_verifier; | 1132 | goto out_set_verifier; |
1149 | 1133 | ||
1150 | /* Force a full look up iff the parent directory has changed */ | 1134 | /* Force a full look up iff the parent directory has changed */ |
1151 | if (!nfs_is_exclusive_create(dir, nd) && nfs_check_verifier(dir, dentry)) { | 1135 | if (!nfs_is_exclusive_create(dir, flags) && nfs_check_verifier(dir, dentry)) { |
1152 | if (nfs_lookup_verify_inode(inode, nd)) | 1136 | if (nfs_lookup_verify_inode(inode, flags)) |
1153 | goto out_zap_parent; | 1137 | goto out_zap_parent; |
1154 | goto out_valid; | 1138 | goto out_valid; |
1155 | } | 1139 | } |
@@ -1286,7 +1270,7 @@ const struct dentry_operations nfs_dentry_operations = { | |||
1286 | .d_release = nfs_d_release, | 1270 | .d_release = nfs_d_release, |
1287 | }; | 1271 | }; |
1288 | 1272 | ||
1289 | static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) | 1273 | static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags) |
1290 | { | 1274 | { |
1291 | struct dentry *res; | 1275 | struct dentry *res; |
1292 | struct dentry *parent; | 1276 | struct dentry *parent; |
@@ -1307,7 +1291,7 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru | |||
1307 | * If we're doing an exclusive create, optimize away the lookup | 1291 | * If we're doing an exclusive create, optimize away the lookup |
1308 | * but don't hash the dentry. | 1292 | * but don't hash the dentry. |
1309 | */ | 1293 | */ |
1310 | if (nfs_is_exclusive_create(dir, nd)) { | 1294 | if (nfs_is_exclusive_create(dir, flags)) { |
1311 | d_instantiate(dentry, NULL); | 1295 | d_instantiate(dentry, NULL); |
1312 | res = NULL; | 1296 | res = NULL; |
1313 | goto out; | 1297 | goto out; |
@@ -1354,7 +1338,7 @@ out: | |||
1354 | } | 1338 | } |
1355 | 1339 | ||
1356 | #ifdef CONFIG_NFS_V4 | 1340 | #ifdef CONFIG_NFS_V4 |
1357 | static int nfs4_lookup_revalidate(struct dentry *, struct nameidata *); | 1341 | static int nfs4_lookup_revalidate(struct dentry *, unsigned int); |
1358 | 1342 | ||
1359 | const struct dentry_operations nfs4_dentry_operations = { | 1343 | const struct dentry_operations nfs4_dentry_operations = { |
1360 | .d_revalidate = nfs4_lookup_revalidate, | 1344 | .d_revalidate = nfs4_lookup_revalidate, |
@@ -1364,24 +1348,6 @@ const struct dentry_operations nfs4_dentry_operations = { | |||
1364 | .d_release = nfs_d_release, | 1348 | .d_release = nfs_d_release, |
1365 | }; | 1349 | }; |
1366 | 1350 | ||
1367 | /* | ||
1368 | * Use intent information to determine whether we need to substitute | ||
1369 | * the NFSv4-style stateful OPEN for the LOOKUP call | ||
1370 | */ | ||
1371 | static int is_atomic_open(struct nameidata *nd) | ||
1372 | { | ||
1373 | if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_OPEN) == 0) | ||
1374 | return 0; | ||
1375 | /* NFS does not (yet) have a stateful open for directories */ | ||
1376 | if (nd->flags & LOOKUP_DIRECTORY) | ||
1377 | return 0; | ||
1378 | /* Are we trying to write to a read only partition? */ | ||
1379 | if (__mnt_is_readonly(nd->path.mnt) && | ||
1380 | (nd->intent.open.flags & (O_CREAT|O_TRUNC|O_ACCMODE))) | ||
1381 | return 0; | ||
1382 | return 1; | ||
1383 | } | ||
1384 | |||
1385 | static fmode_t flags_to_mode(int flags) | 1351 | static fmode_t flags_to_mode(int flags) |
1386 | { | 1352 | { |
1387 | fmode_t res = (__force fmode_t)flags & FMODE_EXEC; | 1353 | fmode_t res = (__force fmode_t)flags & FMODE_EXEC; |
@@ -1403,136 +1369,143 @@ static int do_open(struct inode *inode, struct file *filp) | |||
1403 | return 0; | 1369 | return 0; |
1404 | } | 1370 | } |
1405 | 1371 | ||
1406 | static int nfs_intent_set_file(struct nameidata *nd, struct nfs_open_context *ctx) | 1372 | static int nfs_finish_open(struct nfs_open_context *ctx, |
1373 | struct dentry *dentry, | ||
1374 | struct file *file, unsigned open_flags, | ||
1375 | int *opened) | ||
1407 | { | 1376 | { |
1408 | struct file *filp; | 1377 | int err; |
1409 | int ret = 0; | 1378 | |
1379 | if (ctx->dentry != dentry) { | ||
1380 | dput(ctx->dentry); | ||
1381 | ctx->dentry = dget(dentry); | ||
1382 | } | ||
1410 | 1383 | ||
1411 | /* If the open_intent is for execute, we have an extra check to make */ | 1384 | /* If the open_intent is for execute, we have an extra check to make */ |
1412 | if (ctx->mode & FMODE_EXEC) { | 1385 | if (ctx->mode & FMODE_EXEC) { |
1413 | ret = nfs_may_open(ctx->dentry->d_inode, | 1386 | err = nfs_may_open(dentry->d_inode, ctx->cred, open_flags); |
1414 | ctx->cred, | 1387 | if (err < 0) |
1415 | nd->intent.open.flags); | ||
1416 | if (ret < 0) | ||
1417 | goto out; | 1388 | goto out; |
1418 | } | 1389 | } |
1419 | filp = lookup_instantiate_filp(nd, ctx->dentry, do_open); | 1390 | |
1420 | if (IS_ERR(filp)) | 1391 | err = finish_open(file, dentry, do_open, opened); |
1421 | ret = PTR_ERR(filp); | 1392 | if (err) |
1422 | else | 1393 | goto out; |
1423 | nfs_file_set_open_context(filp, ctx); | 1394 | nfs_file_set_open_context(file, ctx); |
1395 | |||
1424 | out: | 1396 | out: |
1425 | put_nfs_open_context(ctx); | 1397 | put_nfs_open_context(ctx); |
1426 | return ret; | 1398 | return err; |
1427 | } | 1399 | } |
1428 | 1400 | ||
1429 | static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | 1401 | static int nfs_atomic_open(struct inode *dir, struct dentry *dentry, |
1402 | struct file *file, unsigned open_flags, | ||
1403 | umode_t mode, int *opened) | ||
1430 | { | 1404 | { |
1431 | struct nfs_open_context *ctx; | 1405 | struct nfs_open_context *ctx; |
1432 | struct iattr attr; | 1406 | struct dentry *res; |
1433 | struct dentry *res = NULL; | 1407 | struct iattr attr = { .ia_valid = ATTR_OPEN }; |
1434 | struct inode *inode; | 1408 | struct inode *inode; |
1435 | int open_flags; | ||
1436 | int err; | 1409 | int err; |
1437 | 1410 | ||
1438 | dfprintk(VFS, "NFS: atomic_lookup(%s/%ld), %s\n", | 1411 | /* Expect a negative dentry */ |
1412 | BUG_ON(dentry->d_inode); | ||
1413 | |||
1414 | dfprintk(VFS, "NFS: atomic_open(%s/%ld), %s\n", | ||
1439 | dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); | 1415 | dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); |
1440 | 1416 | ||
1441 | /* Check that we are indeed trying to open this file */ | 1417 | /* NFS only supports OPEN on regular files */ |
1442 | if (!is_atomic_open(nd)) | 1418 | if ((open_flags & O_DIRECTORY)) { |
1419 | if (!d_unhashed(dentry)) { | ||
1420 | /* | ||
1421 | * Hashed negative dentry with O_DIRECTORY: dentry was | ||
1422 | * revalidated and is fine, no need to perform lookup | ||
1423 | * again | ||
1424 | */ | ||
1425 | return -ENOENT; | ||
1426 | } | ||
1443 | goto no_open; | 1427 | goto no_open; |
1444 | |||
1445 | if (dentry->d_name.len > NFS_SERVER(dir)->namelen) { | ||
1446 | res = ERR_PTR(-ENAMETOOLONG); | ||
1447 | goto out; | ||
1448 | } | ||
1449 | |||
1450 | /* Let vfs_create() deal with O_EXCL. Instantiate, but don't hash | ||
1451 | * the dentry. */ | ||
1452 | if (nd->flags & LOOKUP_EXCL) { | ||
1453 | d_instantiate(dentry, NULL); | ||
1454 | goto out; | ||
1455 | } | 1428 | } |
1456 | 1429 | ||
1457 | open_flags = nd->intent.open.flags; | 1430 | if (dentry->d_name.len > NFS_SERVER(dir)->namelen) |
1458 | attr.ia_valid = ATTR_OPEN; | 1431 | return -ENAMETOOLONG; |
1459 | |||
1460 | ctx = create_nfs_open_context(dentry, open_flags); | ||
1461 | res = ERR_CAST(ctx); | ||
1462 | if (IS_ERR(ctx)) | ||
1463 | goto out; | ||
1464 | 1432 | ||
1465 | if (nd->flags & LOOKUP_CREATE) { | 1433 | if (open_flags & O_CREAT) { |
1466 | attr.ia_mode = nd->intent.open.create_mode; | ||
1467 | attr.ia_valid |= ATTR_MODE; | 1434 | attr.ia_valid |= ATTR_MODE; |
1468 | attr.ia_mode &= ~current_umask(); | 1435 | attr.ia_mode = mode & ~current_umask(); |
1469 | } else | 1436 | } |
1470 | open_flags &= ~(O_EXCL | O_CREAT); | ||
1471 | |||
1472 | if (open_flags & O_TRUNC) { | 1437 | if (open_flags & O_TRUNC) { |
1473 | attr.ia_valid |= ATTR_SIZE; | 1438 | attr.ia_valid |= ATTR_SIZE; |
1474 | attr.ia_size = 0; | 1439 | attr.ia_size = 0; |
1475 | } | 1440 | } |
1476 | 1441 | ||
1477 | /* Open the file on the server */ | 1442 | ctx = create_nfs_open_context(dentry, open_flags); |
1443 | err = PTR_ERR(ctx); | ||
1444 | if (IS_ERR(ctx)) | ||
1445 | goto out; | ||
1446 | |||
1478 | nfs_block_sillyrename(dentry->d_parent); | 1447 | nfs_block_sillyrename(dentry->d_parent); |
1479 | inode = NFS_PROTO(dir)->open_context(dir, ctx, open_flags, &attr); | 1448 | inode = NFS_PROTO(dir)->open_context(dir, ctx, open_flags, &attr); |
1449 | d_drop(dentry); | ||
1480 | if (IS_ERR(inode)) { | 1450 | if (IS_ERR(inode)) { |
1481 | nfs_unblock_sillyrename(dentry->d_parent); | 1451 | nfs_unblock_sillyrename(dentry->d_parent); |
1482 | put_nfs_open_context(ctx); | 1452 | put_nfs_open_context(ctx); |
1483 | switch (PTR_ERR(inode)) { | 1453 | err = PTR_ERR(inode); |
1484 | /* Make a negative dentry */ | 1454 | switch (err) { |
1485 | case -ENOENT: | 1455 | case -ENOENT: |
1486 | d_add(dentry, NULL); | 1456 | d_add(dentry, NULL); |
1487 | res = NULL; | 1457 | break; |
1488 | goto out; | 1458 | case -EISDIR: |
1489 | /* This turned out not to be a regular file */ | 1459 | case -ENOTDIR: |
1490 | case -EISDIR: | 1460 | goto no_open; |
1491 | case -ENOTDIR: | 1461 | case -ELOOP: |
1462 | if (!(open_flags & O_NOFOLLOW)) | ||
1492 | goto no_open; | 1463 | goto no_open; |
1493 | case -ELOOP: | 1464 | break; |
1494 | if (!(nd->intent.open.flags & O_NOFOLLOW)) | ||
1495 | goto no_open; | ||
1496 | /* case -EINVAL: */ | 1465 | /* case -EINVAL: */ |
1497 | default: | 1466 | default: |
1498 | res = ERR_CAST(inode); | 1467 | break; |
1499 | goto out; | ||
1500 | } | 1468 | } |
1469 | goto out; | ||
1501 | } | 1470 | } |
1502 | res = d_add_unique(dentry, inode); | 1471 | res = d_add_unique(dentry, inode); |
1503 | nfs_unblock_sillyrename(dentry->d_parent); | 1472 | if (res != NULL) |
1504 | if (res != NULL) { | ||
1505 | dput(ctx->dentry); | ||
1506 | ctx->dentry = dget(res); | ||
1507 | dentry = res; | 1473 | dentry = res; |
1508 | } | 1474 | |
1509 | err = nfs_intent_set_file(nd, ctx); | 1475 | nfs_unblock_sillyrename(dentry->d_parent); |
1510 | if (err < 0) { | ||
1511 | if (res != NULL) | ||
1512 | dput(res); | ||
1513 | return ERR_PTR(err); | ||
1514 | } | ||
1515 | out: | ||
1516 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); | 1476 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); |
1517 | return res; | 1477 | |
1478 | err = nfs_finish_open(ctx, dentry, file, open_flags, opened); | ||
1479 | |||
1480 | dput(res); | ||
1481 | out: | ||
1482 | return err; | ||
1483 | |||
1518 | no_open: | 1484 | no_open: |
1519 | return nfs_lookup(dir, dentry, nd); | 1485 | res = nfs_lookup(dir, dentry, 0); |
1486 | err = PTR_ERR(res); | ||
1487 | if (IS_ERR(res)) | ||
1488 | goto out; | ||
1489 | |||
1490 | return finish_no_open(file, res); | ||
1520 | } | 1491 | } |
1521 | 1492 | ||
1522 | static int nfs4_lookup_revalidate(struct dentry *dentry, struct nameidata *nd) | 1493 | static int nfs4_lookup_revalidate(struct dentry *dentry, unsigned int flags) |
1523 | { | 1494 | { |
1524 | struct dentry *parent = NULL; | 1495 | struct dentry *parent = NULL; |
1525 | struct inode *inode; | 1496 | struct inode *inode; |
1526 | struct inode *dir; | 1497 | struct inode *dir; |
1527 | int openflags, ret = 0; | 1498 | int ret = 0; |
1528 | 1499 | ||
1529 | if (nd->flags & LOOKUP_RCU) | 1500 | if (flags & LOOKUP_RCU) |
1530 | return -ECHILD; | 1501 | return -ECHILD; |
1531 | 1502 | ||
1532 | inode = dentry->d_inode; | 1503 | if (!(flags & LOOKUP_OPEN) || (flags & LOOKUP_DIRECTORY)) |
1533 | if (!is_atomic_open(nd) || d_mountpoint(dentry)) | 1504 | goto no_open; |
1505 | if (d_mountpoint(dentry)) | ||
1534 | goto no_open; | 1506 | goto no_open; |
1535 | 1507 | ||
1508 | inode = dentry->d_inode; | ||
1536 | parent = dget_parent(dentry); | 1509 | parent = dget_parent(dentry); |
1537 | dir = parent->d_inode; | 1510 | dir = parent->d_inode; |
1538 | 1511 | ||
@@ -1540,7 +1513,7 @@ static int nfs4_lookup_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
1540 | * optimize away revalidation of negative dentries. | 1513 | * optimize away revalidation of negative dentries. |
1541 | */ | 1514 | */ |
1542 | if (inode == NULL) { | 1515 | if (inode == NULL) { |
1543 | if (!nfs_neg_need_reval(dir, dentry, nd)) | 1516 | if (!nfs_neg_need_reval(dir, dentry, flags)) |
1544 | ret = 1; | 1517 | ret = 1; |
1545 | goto out; | 1518 | goto out; |
1546 | } | 1519 | } |
@@ -1548,9 +1521,8 @@ static int nfs4_lookup_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
1548 | /* NFS only supports OPEN on regular files */ | 1521 | /* NFS only supports OPEN on regular files */ |
1549 | if (!S_ISREG(inode->i_mode)) | 1522 | if (!S_ISREG(inode->i_mode)) |
1550 | goto no_open_dput; | 1523 | goto no_open_dput; |
1551 | openflags = nd->intent.open.flags; | ||
1552 | /* We cannot do exclusive creation on a positive dentry */ | 1524 | /* We cannot do exclusive creation on a positive dentry */ |
1553 | if ((openflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) | 1525 | if (flags & LOOKUP_EXCL) |
1554 | goto no_open_dput; | 1526 | goto no_open_dput; |
1555 | 1527 | ||
1556 | /* Let f_op->open() actually open (and revalidate) the file */ | 1528 | /* Let f_op->open() actually open (and revalidate) the file */ |
@@ -1563,48 +1535,7 @@ out: | |||
1563 | no_open_dput: | 1535 | no_open_dput: |
1564 | dput(parent); | 1536 | dput(parent); |
1565 | no_open: | 1537 | no_open: |
1566 | return nfs_lookup_revalidate(dentry, nd); | 1538 | return nfs_lookup_revalidate(dentry, flags); |
1567 | } | ||
1568 | |||
1569 | static int nfs_open_create(struct inode *dir, struct dentry *dentry, | ||
1570 | umode_t mode, struct nameidata *nd) | ||
1571 | { | ||
1572 | struct nfs_open_context *ctx = NULL; | ||
1573 | struct iattr attr; | ||
1574 | int error; | ||
1575 | int open_flags = O_CREAT|O_EXCL; | ||
1576 | |||
1577 | dfprintk(VFS, "NFS: create(%s/%ld), %s\n", | ||
1578 | dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); | ||
1579 | |||
1580 | attr.ia_mode = mode; | ||
1581 | attr.ia_valid = ATTR_MODE; | ||
1582 | |||
1583 | if (nd) | ||
1584 | open_flags = nd->intent.open.flags; | ||
1585 | |||
1586 | ctx = create_nfs_open_context(dentry, open_flags); | ||
1587 | error = PTR_ERR(ctx); | ||
1588 | if (IS_ERR(ctx)) | ||
1589 | goto out_err_drop; | ||
1590 | |||
1591 | error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, ctx); | ||
1592 | if (error != 0) | ||
1593 | goto out_put_ctx; | ||
1594 | if (nd) { | ||
1595 | error = nfs_intent_set_file(nd, ctx); | ||
1596 | if (error < 0) | ||
1597 | goto out_err; | ||
1598 | } else { | ||
1599 | put_nfs_open_context(ctx); | ||
1600 | } | ||
1601 | return 0; | ||
1602 | out_put_ctx: | ||
1603 | put_nfs_open_context(ctx); | ||
1604 | out_err_drop: | ||
1605 | d_drop(dentry); | ||
1606 | out_err: | ||
1607 | return error; | ||
1608 | } | 1539 | } |
1609 | 1540 | ||
1610 | #endif /* CONFIG_NFSV4 */ | 1541 | #endif /* CONFIG_NFSV4 */ |
@@ -1658,11 +1589,11 @@ out_error: | |||
1658 | * reply path made it appear to have failed. | 1589 | * reply path made it appear to have failed. |
1659 | */ | 1590 | */ |
1660 | static int nfs_create(struct inode *dir, struct dentry *dentry, | 1591 | static int nfs_create(struct inode *dir, struct dentry *dentry, |
1661 | umode_t mode, struct nameidata *nd) | 1592 | umode_t mode, bool excl) |
1662 | { | 1593 | { |
1663 | struct iattr attr; | 1594 | struct iattr attr; |
1595 | int open_flags = excl ? O_CREAT | O_EXCL : O_CREAT; | ||
1664 | int error; | 1596 | int error; |
1665 | int open_flags = O_CREAT|O_EXCL; | ||
1666 | 1597 | ||
1667 | dfprintk(VFS, "NFS: create(%s/%ld), %s\n", | 1598 | dfprintk(VFS, "NFS: create(%s/%ld), %s\n", |
1668 | dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); | 1599 | dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); |
@@ -1670,10 +1601,7 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, | |||
1670 | attr.ia_mode = mode; | 1601 | attr.ia_mode = mode; |
1671 | attr.ia_valid = ATTR_MODE; | 1602 | attr.ia_valid = ATTR_MODE; |
1672 | 1603 | ||
1673 | if (nd) | 1604 | error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags); |
1674 | open_flags = nd->intent.open.flags; | ||
1675 | |||
1676 | error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, NULL); | ||
1677 | if (error != 0) | 1605 | if (error != 0) |
1678 | goto out_err; | 1606 | goto out_err; |
1679 | return 0; | 1607 | return 0; |
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 9a4cbfc85d81..48253372ab1d 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
@@ -484,6 +484,7 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) | |||
484 | 484 | ||
485 | list_for_each_entry_safe(req, tmp, &reqs, wb_list) { | 485 | list_for_each_entry_safe(req, tmp, &reqs, wb_list) { |
486 | if (!nfs_pageio_add_request(&desc, req)) { | 486 | if (!nfs_pageio_add_request(&desc, req)) { |
487 | nfs_list_remove_request(req); | ||
487 | nfs_list_add_request(req, &failed); | 488 | nfs_list_add_request(req, &failed); |
488 | spin_lock(cinfo.lock); | 489 | spin_lock(cinfo.lock); |
489 | dreq->flags = 0; | 490 | dreq->flags = 0; |
@@ -494,8 +495,11 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) | |||
494 | } | 495 | } |
495 | nfs_pageio_complete(&desc); | 496 | nfs_pageio_complete(&desc); |
496 | 497 | ||
497 | while (!list_empty(&failed)) | 498 | while (!list_empty(&failed)) { |
499 | req = nfs_list_entry(failed.next); | ||
500 | nfs_list_remove_request(req); | ||
498 | nfs_unlock_and_release_request(req); | 501 | nfs_unlock_and_release_request(req); |
502 | } | ||
499 | 503 | ||
500 | if (put_dreq(dreq)) | 504 | if (put_dreq(dreq)) |
501 | nfs_direct_write_complete(dreq, dreq->inode); | 505 | nfs_direct_write_complete(dreq, dreq->inode); |
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c index 8abfb19bd3aa..a67990f90bd7 100644 --- a/fs/nfs/getroot.c +++ b/fs/nfs/getroot.c | |||
@@ -62,7 +62,7 @@ static int nfs_superblock_set_dummy_root(struct super_block *sb, struct inode *i | |||
62 | */ | 62 | */ |
63 | spin_lock(&sb->s_root->d_inode->i_lock); | 63 | spin_lock(&sb->s_root->d_inode->i_lock); |
64 | spin_lock(&sb->s_root->d_lock); | 64 | spin_lock(&sb->s_root->d_lock); |
65 | list_del_init(&sb->s_root->d_alias); | 65 | hlist_del_init(&sb->s_root->d_alias); |
66 | spin_unlock(&sb->s_root->d_lock); | 66 | spin_unlock(&sb->s_root->d_lock); |
67 | spin_unlock(&sb->s_root->d_inode->i_lock); | 67 | spin_unlock(&sb->s_root->d_inode->i_lock); |
68 | } | 68 | } |
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index f3344f7f46a9..f580358cad62 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c | |||
@@ -314,7 +314,7 @@ static void nfs3_free_createdata(struct nfs3_createdata *data) | |||
314 | */ | 314 | */ |
315 | static int | 315 | static int |
316 | nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | 316 | nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, |
317 | int flags, struct nfs_open_context *ctx) | 317 | int flags) |
318 | { | 318 | { |
319 | struct nfs3_createdata *data; | 319 | struct nfs3_createdata *data; |
320 | umode_t mode = sattr->ia_mode; | 320 | umode_t mode = sattr->ia_mode; |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 7d387cb8ceb5..006e98da730a 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -2804,39 +2804,24 @@ static int nfs4_proc_readlink(struct inode *inode, struct page *page, | |||
2804 | } | 2804 | } |
2805 | 2805 | ||
2806 | /* | 2806 | /* |
2807 | * Got race? | 2807 | * This is just for mknod. open(O_CREAT) will always do ->open_context(). |
2808 | * We will need to arrange for the VFS layer to provide an atomic open. | ||
2809 | * Until then, this create/open method is prone to inefficiency and race | ||
2810 | * conditions due to the lookup, create, and open VFS calls from sys_open() | ||
2811 | * placed on the wire. | ||
2812 | * | ||
2813 | * Given the above sorry state of affairs, I'm simply sending an OPEN. | ||
2814 | * The file will be opened again in the subsequent VFS open call | ||
2815 | * (nfs4_proc_file_open). | ||
2816 | * | ||
2817 | * The open for read will just hang around to be used by any process that | ||
2818 | * opens the file O_RDONLY. This will all be resolved with the VFS changes. | ||
2819 | */ | 2808 | */ |
2820 | |||
2821 | static int | 2809 | static int |
2822 | nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | 2810 | nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, |
2823 | int flags, struct nfs_open_context *ctx) | 2811 | int flags) |
2824 | { | 2812 | { |
2825 | struct dentry *de = dentry; | 2813 | struct nfs_open_context *ctx; |
2826 | struct nfs4_state *state; | 2814 | struct nfs4_state *state; |
2827 | struct rpc_cred *cred = NULL; | ||
2828 | struct nfs4_threshold **thp = NULL; | ||
2829 | fmode_t fmode = 0; | ||
2830 | int status = 0; | 2815 | int status = 0; |
2831 | 2816 | ||
2832 | if (ctx != NULL) { | 2817 | ctx = alloc_nfs_open_context(dentry, FMODE_READ); |
2833 | cred = ctx->cred; | 2818 | if (IS_ERR(ctx)) |
2834 | de = ctx->dentry; | 2819 | return PTR_ERR(ctx); |
2835 | fmode = ctx->mode; | 2820 | |
2836 | thp = &ctx->mdsthreshold; | ||
2837 | } | ||
2838 | sattr->ia_mode &= ~current_umask(); | 2821 | sattr->ia_mode &= ~current_umask(); |
2839 | state = nfs4_do_open(dir, de, fmode, flags, sattr, cred, thp); | 2822 | state = nfs4_do_open(dir, dentry, ctx->mode, |
2823 | flags, sattr, ctx->cred, | ||
2824 | &ctx->mdsthreshold); | ||
2840 | d_drop(dentry); | 2825 | d_drop(dentry); |
2841 | if (IS_ERR(state)) { | 2826 | if (IS_ERR(state)) { |
2842 | status = PTR_ERR(state); | 2827 | status = PTR_ERR(state); |
@@ -2844,11 +2829,9 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | |||
2844 | } | 2829 | } |
2845 | d_add(dentry, igrab(state->inode)); | 2830 | d_add(dentry, igrab(state->inode)); |
2846 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); | 2831 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); |
2847 | if (ctx != NULL) | 2832 | ctx->state = state; |
2848 | ctx->state = state; | ||
2849 | else | ||
2850 | nfs4_close_sync(state, fmode); | ||
2851 | out: | 2833 | out: |
2834 | put_nfs_open_context(ctx); | ||
2852 | return status; | 2835 | return status; |
2853 | } | 2836 | } |
2854 | 2837 | ||
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index cf6499742b10..c5ed1c0a8ab7 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c | |||
@@ -259,7 +259,7 @@ static void nfs_free_createdata(const struct nfs_createdata *data) | |||
259 | 259 | ||
260 | static int | 260 | static int |
261 | nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | 261 | nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, |
262 | int flags, struct nfs_open_context *ctx) | 262 | int flags) |
263 | { | 263 | { |
264 | struct nfs_createdata *data; | 264 | struct nfs_createdata *data; |
265 | struct rpc_message msg = { | 265 | struct rpc_message msg = { |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 9d33fb22f287..9bad4e753066 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -2418,7 +2418,7 @@ static struct dentry *nfs_fs_mount_common(struct file_system_type *fs_type, | |||
2418 | sb_mntdata.mntflags |= MS_SYNCHRONOUS; | 2418 | sb_mntdata.mntflags |= MS_SYNCHRONOUS; |
2419 | 2419 | ||
2420 | /* Get a superblock - note that we may end up sharing one that already exists */ | 2420 | /* Get a superblock - note that we may end up sharing one that already exists */ |
2421 | s = sget(fs_type, compare_super, nfs_set_super, &sb_mntdata); | 2421 | s = sget(fs_type, compare_super, nfs_set_super, flags, &sb_mntdata); |
2422 | if (IS_ERR(s)) { | 2422 | if (IS_ERR(s)) { |
2423 | mntroot = ERR_CAST(s); | 2423 | mntroot = ERR_CAST(s); |
2424 | goto out_err_nosb; | 2424 | goto out_err_nosb; |
@@ -2859,6 +2859,8 @@ static struct dentry *nfs4_try_mount(int flags, const char *dev_name, | |||
2859 | 2859 | ||
2860 | dfprintk(MOUNT, "--> nfs4_try_mount()\n"); | 2860 | dfprintk(MOUNT, "--> nfs4_try_mount()\n"); |
2861 | 2861 | ||
2862 | mount_info->fill_super = nfs4_fill_super; | ||
2863 | |||
2862 | export_path = data->nfs_server.export_path; | 2864 | export_path = data->nfs_server.export_path; |
2863 | data->nfs_server.export_path = "/"; | 2865 | data->nfs_server.export_path = "/"; |
2864 | root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, mount_info, | 2866 | root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, mount_info, |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index c8bd9c3be7f7..05d9eee6be3a 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -1329,7 +1329,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1329 | err = 0; | 1329 | err = 0; |
1330 | switch (type) { | 1330 | switch (type) { |
1331 | case S_IFREG: | 1331 | case S_IFREG: |
1332 | host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL); | 1332 | host_err = vfs_create(dirp, dchild, iap->ia_mode, true); |
1333 | if (!host_err) | 1333 | if (!host_err) |
1334 | nfsd_check_ignore_resizing(iap); | 1334 | nfsd_check_ignore_resizing(iap); |
1335 | break; | 1335 | break; |
@@ -1492,7 +1492,7 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1492 | goto out; | 1492 | goto out; |
1493 | } | 1493 | } |
1494 | 1494 | ||
1495 | host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL); | 1495 | host_err = vfs_create(dirp, dchild, iap->ia_mode, true); |
1496 | if (host_err < 0) { | 1496 | if (host_err < 0) { |
1497 | fh_drop_write(fhp); | 1497 | fh_drop_write(fhp); |
1498 | goto out_nfserr; | 1498 | goto out_nfserr; |
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c index b72847988b78..1d0c0b84c5a3 100644 --- a/fs/nilfs2/namei.c +++ b/fs/nilfs2/namei.c | |||
@@ -63,7 +63,7 @@ static inline int nilfs_add_nondir(struct dentry *dentry, struct inode *inode) | |||
63 | */ | 63 | */ |
64 | 64 | ||
65 | static struct dentry * | 65 | static struct dentry * |
66 | nilfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | 66 | nilfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) |
67 | { | 67 | { |
68 | struct inode *inode; | 68 | struct inode *inode; |
69 | ino_t ino; | 69 | ino_t ino; |
@@ -85,7 +85,7 @@ nilfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | |||
85 | * with d_instantiate(). | 85 | * with d_instantiate(). |
86 | */ | 86 | */ |
87 | static int nilfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 87 | static int nilfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
88 | struct nameidata *nd) | 88 | bool excl) |
89 | { | 89 | { |
90 | struct inode *inode; | 90 | struct inode *inode; |
91 | struct nilfs_transaction_info ti; | 91 | struct nilfs_transaction_info ti; |
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 1099a76cee59..d57c42f974ea 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c | |||
@@ -1288,7 +1288,8 @@ nilfs_mount(struct file_system_type *fs_type, int flags, | |||
1288 | err = -EBUSY; | 1288 | err = -EBUSY; |
1289 | goto failed; | 1289 | goto failed; |
1290 | } | 1290 | } |
1291 | s = sget(fs_type, nilfs_test_bdev_super, nilfs_set_bdev_super, sd.bdev); | 1291 | s = sget(fs_type, nilfs_test_bdev_super, nilfs_set_bdev_super, flags, |
1292 | sd.bdev); | ||
1292 | mutex_unlock(&sd.bdev->bd_fsfreeze_mutex); | 1293 | mutex_unlock(&sd.bdev->bd_fsfreeze_mutex); |
1293 | if (IS_ERR(s)) { | 1294 | if (IS_ERR(s)) { |
1294 | err = PTR_ERR(s); | 1295 | err = PTR_ERR(s); |
@@ -1301,7 +1302,6 @@ nilfs_mount(struct file_system_type *fs_type, int flags, | |||
1301 | s_new = true; | 1302 | s_new = true; |
1302 | 1303 | ||
1303 | /* New superblock instance created */ | 1304 | /* New superblock instance created */ |
1304 | s->s_flags = flags; | ||
1305 | s->s_mode = mode; | 1305 | s->s_mode = mode; |
1306 | strlcpy(s->s_id, bdevname(sd.bdev, b), sizeof(s->s_id)); | 1306 | strlcpy(s->s_id, bdevname(sd.bdev, b), sizeof(s->s_id)); |
1307 | sb_set_blocksize(s, block_size(sd.bdev)); | 1307 | sb_set_blocksize(s, block_size(sd.bdev)); |
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index b39c5c161adb..6baadb5a8430 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c | |||
@@ -52,6 +52,7 @@ void __fsnotify_vfsmount_delete(struct vfsmount *mnt) | |||
52 | void __fsnotify_update_child_dentry_flags(struct inode *inode) | 52 | void __fsnotify_update_child_dentry_flags(struct inode *inode) |
53 | { | 53 | { |
54 | struct dentry *alias; | 54 | struct dentry *alias; |
55 | struct hlist_node *p; | ||
55 | int watched; | 56 | int watched; |
56 | 57 | ||
57 | if (!S_ISDIR(inode->i_mode)) | 58 | if (!S_ISDIR(inode->i_mode)) |
@@ -63,7 +64,7 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode) | |||
63 | spin_lock(&inode->i_lock); | 64 | spin_lock(&inode->i_lock); |
64 | /* run all of the dentries associated with this inode. Since this is a | 65 | /* run all of the dentries associated with this inode. Since this is a |
65 | * directory, there damn well better only be one item on this list */ | 66 | * directory, there damn well better only be one item on this list */ |
66 | list_for_each_entry(alias, &inode->i_dentry, d_alias) { | 67 | hlist_for_each_entry(alias, p, &inode->i_dentry, d_alias) { |
67 | struct dentry *child; | 68 | struct dentry *child; |
68 | 69 | ||
69 | /* run all of the children of the original inode and fix their | 70 | /* run all of the children of the original inode and fix their |
diff --git a/fs/ntfs/namei.c b/fs/ntfs/namei.c index 358273e59ade..436f36037e09 100644 --- a/fs/ntfs/namei.c +++ b/fs/ntfs/namei.c | |||
@@ -101,7 +101,7 @@ | |||
101 | * Locking: Caller must hold i_mutex on the directory. | 101 | * Locking: Caller must hold i_mutex on the directory. |
102 | */ | 102 | */ |
103 | static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent, | 103 | static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent, |
104 | struct nameidata *nd) | 104 | unsigned int flags) |
105 | { | 105 | { |
106 | ntfs_volume *vol = NTFS_SB(dir_ino->i_sb); | 106 | ntfs_volume *vol = NTFS_SB(dir_ino->i_sb); |
107 | struct inode *dent_inode; | 107 | struct inode *dent_inode; |
diff --git a/fs/ocfs2/dcache.c b/fs/ocfs2/dcache.c index e5ba34818332..8db4b58b2e4b 100644 --- a/fs/ocfs2/dcache.c +++ b/fs/ocfs2/dcache.c | |||
@@ -49,14 +49,13 @@ void ocfs2_dentry_attach_gen(struct dentry *dentry) | |||
49 | } | 49 | } |
50 | 50 | ||
51 | 51 | ||
52 | static int ocfs2_dentry_revalidate(struct dentry *dentry, | 52 | static int ocfs2_dentry_revalidate(struct dentry *dentry, unsigned int flags) |
53 | struct nameidata *nd) | ||
54 | { | 53 | { |
55 | struct inode *inode; | 54 | struct inode *inode; |
56 | int ret = 0; /* if all else fails, just return false */ | 55 | int ret = 0; /* if all else fails, just return false */ |
57 | struct ocfs2_super *osb; | 56 | struct ocfs2_super *osb; |
58 | 57 | ||
59 | if (nd && nd->flags & LOOKUP_RCU) | 58 | if (flags & LOOKUP_RCU) |
60 | return -ECHILD; | 59 | return -ECHILD; |
61 | 60 | ||
62 | inode = dentry->d_inode; | 61 | inode = dentry->d_inode; |
@@ -170,13 +169,11 @@ struct dentry *ocfs2_find_local_alias(struct inode *inode, | |||
170 | u64 parent_blkno, | 169 | u64 parent_blkno, |
171 | int skip_unhashed) | 170 | int skip_unhashed) |
172 | { | 171 | { |
173 | struct list_head *p; | 172 | struct hlist_node *p; |
174 | struct dentry *dentry = NULL; | 173 | struct dentry *dentry; |
175 | 174 | ||
176 | spin_lock(&inode->i_lock); | 175 | spin_lock(&inode->i_lock); |
177 | list_for_each(p, &inode->i_dentry) { | 176 | hlist_for_each_entry(dentry, p, &inode->i_dentry, d_alias) { |
178 | dentry = list_entry(p, struct dentry, d_alias); | ||
179 | |||
180 | spin_lock(&dentry->d_lock); | 177 | spin_lock(&dentry->d_lock); |
181 | if (ocfs2_match_dentry(dentry, parent_blkno, skip_unhashed)) { | 178 | if (ocfs2_match_dentry(dentry, parent_blkno, skip_unhashed)) { |
182 | trace_ocfs2_find_local_alias(dentry->d_name.len, | 179 | trace_ocfs2_find_local_alias(dentry->d_name.len, |
@@ -184,16 +181,13 @@ struct dentry *ocfs2_find_local_alias(struct inode *inode, | |||
184 | 181 | ||
185 | dget_dlock(dentry); | 182 | dget_dlock(dentry); |
186 | spin_unlock(&dentry->d_lock); | 183 | spin_unlock(&dentry->d_lock); |
187 | break; | 184 | spin_unlock(&inode->i_lock); |
185 | return dentry; | ||
188 | } | 186 | } |
189 | spin_unlock(&dentry->d_lock); | 187 | spin_unlock(&dentry->d_lock); |
190 | |||
191 | dentry = NULL; | ||
192 | } | 188 | } |
193 | |||
194 | spin_unlock(&inode->i_lock); | 189 | spin_unlock(&inode->i_lock); |
195 | 190 | return NULL; | |
196 | return dentry; | ||
197 | } | 191 | } |
198 | 192 | ||
199 | DEFINE_SPINLOCK(dentry_attach_lock); | 193 | DEFINE_SPINLOCK(dentry_attach_lock); |
diff --git a/fs/ocfs2/dlmfs/dlmfs.c b/fs/ocfs2/dlmfs/dlmfs.c index e31d6ae013ab..83b6f98e0665 100644 --- a/fs/ocfs2/dlmfs/dlmfs.c +++ b/fs/ocfs2/dlmfs/dlmfs.c | |||
@@ -526,7 +526,7 @@ bail: | |||
526 | static int dlmfs_create(struct inode *dir, | 526 | static int dlmfs_create(struct inode *dir, |
527 | struct dentry *dentry, | 527 | struct dentry *dentry, |
528 | umode_t mode, | 528 | umode_t mode, |
529 | struct nameidata *nd) | 529 | bool excl) |
530 | { | 530 | { |
531 | int status = 0; | 531 | int status = 0; |
532 | struct inode *inode; | 532 | struct inode *inode; |
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 81a4cd22f80b..4f7795fb5fc0 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c | |||
@@ -456,7 +456,7 @@ static void ocfs2_update_lock_stats(struct ocfs2_lock_res *res, int level, | |||
456 | stats->ls_gets++; | 456 | stats->ls_gets++; |
457 | stats->ls_total += ktime_to_ns(kt); | 457 | stats->ls_total += ktime_to_ns(kt); |
458 | /* overflow */ | 458 | /* overflow */ |
459 | if (unlikely(stats->ls_gets) == 0) { | 459 | if (unlikely(stats->ls_gets == 0)) { |
460 | stats->ls_gets++; | 460 | stats->ls_gets++; |
461 | stats->ls_total = ktime_to_ns(kt); | 461 | stats->ls_total = ktime_to_ns(kt); |
462 | } | 462 | } |
@@ -3932,6 +3932,8 @@ unqueue: | |||
3932 | static void ocfs2_schedule_blocked_lock(struct ocfs2_super *osb, | 3932 | static void ocfs2_schedule_blocked_lock(struct ocfs2_super *osb, |
3933 | struct ocfs2_lock_res *lockres) | 3933 | struct ocfs2_lock_res *lockres) |
3934 | { | 3934 | { |
3935 | unsigned long flags; | ||
3936 | |||
3935 | assert_spin_locked(&lockres->l_lock); | 3937 | assert_spin_locked(&lockres->l_lock); |
3936 | 3938 | ||
3937 | if (lockres->l_flags & OCFS2_LOCK_FREEING) { | 3939 | if (lockres->l_flags & OCFS2_LOCK_FREEING) { |
@@ -3945,21 +3947,22 @@ static void ocfs2_schedule_blocked_lock(struct ocfs2_super *osb, | |||
3945 | 3947 | ||
3946 | lockres_or_flags(lockres, OCFS2_LOCK_QUEUED); | 3948 | lockres_or_flags(lockres, OCFS2_LOCK_QUEUED); |
3947 | 3949 | ||
3948 | spin_lock(&osb->dc_task_lock); | 3950 | spin_lock_irqsave(&osb->dc_task_lock, flags); |
3949 | if (list_empty(&lockres->l_blocked_list)) { | 3951 | if (list_empty(&lockres->l_blocked_list)) { |
3950 | list_add_tail(&lockres->l_blocked_list, | 3952 | list_add_tail(&lockres->l_blocked_list, |
3951 | &osb->blocked_lock_list); | 3953 | &osb->blocked_lock_list); |
3952 | osb->blocked_lock_count++; | 3954 | osb->blocked_lock_count++; |
3953 | } | 3955 | } |
3954 | spin_unlock(&osb->dc_task_lock); | 3956 | spin_unlock_irqrestore(&osb->dc_task_lock, flags); |
3955 | } | 3957 | } |
3956 | 3958 | ||
3957 | static void ocfs2_downconvert_thread_do_work(struct ocfs2_super *osb) | 3959 | static void ocfs2_downconvert_thread_do_work(struct ocfs2_super *osb) |
3958 | { | 3960 | { |
3959 | unsigned long processed; | 3961 | unsigned long processed; |
3962 | unsigned long flags; | ||
3960 | struct ocfs2_lock_res *lockres; | 3963 | struct ocfs2_lock_res *lockres; |
3961 | 3964 | ||
3962 | spin_lock(&osb->dc_task_lock); | 3965 | spin_lock_irqsave(&osb->dc_task_lock, flags); |
3963 | /* grab this early so we know to try again if a state change and | 3966 | /* grab this early so we know to try again if a state change and |
3964 | * wake happens part-way through our work */ | 3967 | * wake happens part-way through our work */ |
3965 | osb->dc_work_sequence = osb->dc_wake_sequence; | 3968 | osb->dc_work_sequence = osb->dc_wake_sequence; |
@@ -3972,38 +3975,40 @@ static void ocfs2_downconvert_thread_do_work(struct ocfs2_super *osb) | |||
3972 | struct ocfs2_lock_res, l_blocked_list); | 3975 | struct ocfs2_lock_res, l_blocked_list); |
3973 | list_del_init(&lockres->l_blocked_list); | 3976 | list_del_init(&lockres->l_blocked_list); |
3974 | osb->blocked_lock_count--; | 3977 | osb->blocked_lock_count--; |
3975 | spin_unlock(&osb->dc_task_lock); | 3978 | spin_unlock_irqrestore(&osb->dc_task_lock, flags); |
3976 | 3979 | ||
3977 | BUG_ON(!processed); | 3980 | BUG_ON(!processed); |
3978 | processed--; | 3981 | processed--; |
3979 | 3982 | ||
3980 | ocfs2_process_blocked_lock(osb, lockres); | 3983 | ocfs2_process_blocked_lock(osb, lockres); |
3981 | 3984 | ||
3982 | spin_lock(&osb->dc_task_lock); | 3985 | spin_lock_irqsave(&osb->dc_task_lock, flags); |
3983 | } | 3986 | } |
3984 | spin_unlock(&osb->dc_task_lock); | 3987 | spin_unlock_irqrestore(&osb->dc_task_lock, flags); |
3985 | } | 3988 | } |
3986 | 3989 | ||
3987 | static int ocfs2_downconvert_thread_lists_empty(struct ocfs2_super *osb) | 3990 | static int ocfs2_downconvert_thread_lists_empty(struct ocfs2_super *osb) |
3988 | { | 3991 | { |
3989 | int empty = 0; | 3992 | int empty = 0; |
3993 | unsigned long flags; | ||
3990 | 3994 | ||
3991 | spin_lock(&osb->dc_task_lock); | 3995 | spin_lock_irqsave(&osb->dc_task_lock, flags); |
3992 | if (list_empty(&osb->blocked_lock_list)) | 3996 | if (list_empty(&osb->blocked_lock_list)) |
3993 | empty = 1; | 3997 | empty = 1; |
3994 | 3998 | ||
3995 | spin_unlock(&osb->dc_task_lock); | 3999 | spin_unlock_irqrestore(&osb->dc_task_lock, flags); |
3996 | return empty; | 4000 | return empty; |
3997 | } | 4001 | } |
3998 | 4002 | ||
3999 | static int ocfs2_downconvert_thread_should_wake(struct ocfs2_super *osb) | 4003 | static int ocfs2_downconvert_thread_should_wake(struct ocfs2_super *osb) |
4000 | { | 4004 | { |
4001 | int should_wake = 0; | 4005 | int should_wake = 0; |
4006 | unsigned long flags; | ||
4002 | 4007 | ||
4003 | spin_lock(&osb->dc_task_lock); | 4008 | spin_lock_irqsave(&osb->dc_task_lock, flags); |
4004 | if (osb->dc_work_sequence != osb->dc_wake_sequence) | 4009 | if (osb->dc_work_sequence != osb->dc_wake_sequence) |
4005 | should_wake = 1; | 4010 | should_wake = 1; |
4006 | spin_unlock(&osb->dc_task_lock); | 4011 | spin_unlock_irqrestore(&osb->dc_task_lock, flags); |
4007 | 4012 | ||
4008 | return should_wake; | 4013 | return should_wake; |
4009 | } | 4014 | } |
@@ -4033,10 +4038,12 @@ static int ocfs2_downconvert_thread(void *arg) | |||
4033 | 4038 | ||
4034 | void ocfs2_wake_downconvert_thread(struct ocfs2_super *osb) | 4039 | void ocfs2_wake_downconvert_thread(struct ocfs2_super *osb) |
4035 | { | 4040 | { |
4036 | spin_lock(&osb->dc_task_lock); | 4041 | unsigned long flags; |
4042 | |||
4043 | spin_lock_irqsave(&osb->dc_task_lock, flags); | ||
4037 | /* make sure the voting thread gets a swipe at whatever changes | 4044 | /* make sure the voting thread gets a swipe at whatever changes |
4038 | * the caller may have made to the voting state */ | 4045 | * the caller may have made to the voting state */ |
4039 | osb->dc_wake_sequence++; | 4046 | osb->dc_wake_sequence++; |
4040 | spin_unlock(&osb->dc_task_lock); | 4047 | spin_unlock_irqrestore(&osb->dc_task_lock, flags); |
4041 | wake_up(&osb->dc_event); | 4048 | wake_up(&osb->dc_event); |
4042 | } | 4049 | } |
diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c index 2f5b92ef0e53..70b5863a2d64 100644 --- a/fs/ocfs2/extent_map.c +++ b/fs/ocfs2/extent_map.c | |||
@@ -923,8 +923,6 @@ out_unlock: | |||
923 | 923 | ||
924 | ocfs2_inode_unlock(inode, 0); | 924 | ocfs2_inode_unlock(inode, 0); |
925 | out: | 925 | out: |
926 | if (ret && ret != -ENXIO) | ||
927 | ret = -ENXIO; | ||
928 | return ret; | 926 | return ret; |
929 | } | 927 | } |
930 | 928 | ||
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 061591a3ab08..7602783d7f41 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -1950,7 +1950,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, | |||
1950 | if (ret < 0) | 1950 | if (ret < 0) |
1951 | mlog_errno(ret); | 1951 | mlog_errno(ret); |
1952 | 1952 | ||
1953 | if (file->f_flags & O_SYNC) | 1953 | if (file && (file->f_flags & O_SYNC)) |
1954 | handle->h_sync = 1; | 1954 | handle->h_sync = 1; |
1955 | 1955 | ||
1956 | ocfs2_commit_trans(osb, handle); | 1956 | ocfs2_commit_trans(osb, handle); |
@@ -2422,8 +2422,10 @@ out_dio: | |||
2422 | unaligned_dio = 0; | 2422 | unaligned_dio = 0; |
2423 | } | 2423 | } |
2424 | 2424 | ||
2425 | if (unaligned_dio) | 2425 | if (unaligned_dio) { |
2426 | ocfs2_iocb_clear_unaligned_aio(iocb); | ||
2426 | atomic_dec(&OCFS2_I(inode)->ip_unaligned_aio); | 2427 | atomic_dec(&OCFS2_I(inode)->ip_unaligned_aio); |
2428 | } | ||
2427 | 2429 | ||
2428 | out: | 2430 | out: |
2429 | if (rw_level != -1) | 2431 | if (rw_level != -1) |
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 9f39c640cddf..f1fd0741162b 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
@@ -98,7 +98,7 @@ static int ocfs2_create_symlink_data(struct ocfs2_super *osb, | |||
98 | #define OCFS2_ORPHAN_NAMELEN ((int)(2 * sizeof(u64))) | 98 | #define OCFS2_ORPHAN_NAMELEN ((int)(2 * sizeof(u64))) |
99 | 99 | ||
100 | static struct dentry *ocfs2_lookup(struct inode *dir, struct dentry *dentry, | 100 | static struct dentry *ocfs2_lookup(struct inode *dir, struct dentry *dentry, |
101 | struct nameidata *nd) | 101 | unsigned int flags) |
102 | { | 102 | { |
103 | int status; | 103 | int status; |
104 | u64 blkno; | 104 | u64 blkno; |
@@ -618,7 +618,7 @@ static int ocfs2_mkdir(struct inode *dir, | |||
618 | static int ocfs2_create(struct inode *dir, | 618 | static int ocfs2_create(struct inode *dir, |
619 | struct dentry *dentry, | 619 | struct dentry *dentry, |
620 | umode_t mode, | 620 | umode_t mode, |
621 | struct nameidata *nd) | 621 | bool excl) |
622 | { | 622 | { |
623 | int ret; | 623 | int ret; |
624 | 624 | ||
diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c index 92fcd575775a..0a86e302655f 100644 --- a/fs/ocfs2/quota_global.c +++ b/fs/ocfs2/quota_global.c | |||
@@ -399,8 +399,6 @@ int ocfs2_global_read_info(struct super_block *sb, int type) | |||
399 | msecs_to_jiffies(oinfo->dqi_syncms)); | 399 | msecs_to_jiffies(oinfo->dqi_syncms)); |
400 | 400 | ||
401 | out_err: | 401 | out_err: |
402 | if (status) | ||
403 | mlog_errno(status); | ||
404 | return status; | 402 | return status; |
405 | out_unlock: | 403 | out_unlock: |
406 | ocfs2_unlock_global_qf(oinfo, 0); | 404 | ocfs2_unlock_global_qf(oinfo, 0); |
diff --git a/fs/omfs/dir.c b/fs/omfs/dir.c index f00576ec320f..fb5b3ff79dc6 100644 --- a/fs/omfs/dir.c +++ b/fs/omfs/dir.c | |||
@@ -285,13 +285,13 @@ static int omfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
285 | } | 285 | } |
286 | 286 | ||
287 | static int omfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 287 | static int omfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
288 | struct nameidata *nd) | 288 | bool excl) |
289 | { | 289 | { |
290 | return omfs_add_node(dir, dentry, mode | S_IFREG); | 290 | return omfs_add_node(dir, dentry, mode | S_IFREG); |
291 | } | 291 | } |
292 | 292 | ||
293 | static struct dentry *omfs_lookup(struct inode *dir, struct dentry *dentry, | 293 | static struct dentry *omfs_lookup(struct inode *dir, struct dentry *dentry, |
294 | struct nameidata *nd) | 294 | unsigned int flags) |
295 | { | 295 | { |
296 | struct buffer_head *bh; | 296 | struct buffer_head *bh; |
297 | struct inode *inode = NULL; | 297 | struct inode *inode = NULL; |
@@ -397,10 +397,10 @@ SYSCALL_DEFINE1(fchdir, unsigned int, fd) | |||
397 | { | 397 | { |
398 | struct file *file; | 398 | struct file *file; |
399 | struct inode *inode; | 399 | struct inode *inode; |
400 | int error; | 400 | int error, fput_needed; |
401 | 401 | ||
402 | error = -EBADF; | 402 | error = -EBADF; |
403 | file = fget(fd); | 403 | file = fget_raw_light(fd, &fput_needed); |
404 | if (!file) | 404 | if (!file) |
405 | goto out; | 405 | goto out; |
406 | 406 | ||
@@ -414,7 +414,7 @@ SYSCALL_DEFINE1(fchdir, unsigned int, fd) | |||
414 | if (!error) | 414 | if (!error) |
415 | set_fs_pwd(current->fs, &file->f_path); | 415 | set_fs_pwd(current->fs, &file->f_path); |
416 | out_putf: | 416 | out_putf: |
417 | fput(file); | 417 | fput_light(file, fput_needed); |
418 | out: | 418 | out: |
419 | return error; | 419 | return error; |
420 | } | 420 | } |
@@ -537,25 +537,6 @@ static int chown_common(struct path *path, uid_t user, gid_t group) | |||
537 | return error; | 537 | return error; |
538 | } | 538 | } |
539 | 539 | ||
540 | SYSCALL_DEFINE3(chown, const char __user *, filename, uid_t, user, gid_t, group) | ||
541 | { | ||
542 | struct path path; | ||
543 | int error; | ||
544 | |||
545 | error = user_path(filename, &path); | ||
546 | if (error) | ||
547 | goto out; | ||
548 | error = mnt_want_write(path.mnt); | ||
549 | if (error) | ||
550 | goto out_release; | ||
551 | error = chown_common(&path, user, group); | ||
552 | mnt_drop_write(path.mnt); | ||
553 | out_release: | ||
554 | path_put(&path); | ||
555 | out: | ||
556 | return error; | ||
557 | } | ||
558 | |||
559 | SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user, | 540 | SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user, |
560 | gid_t, group, int, flag) | 541 | gid_t, group, int, flag) |
561 | { | 542 | { |
@@ -583,23 +564,15 @@ out: | |||
583 | return error; | 564 | return error; |
584 | } | 565 | } |
585 | 566 | ||
586 | SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group) | 567 | SYSCALL_DEFINE3(chown, const char __user *, filename, uid_t, user, gid_t, group) |
587 | { | 568 | { |
588 | struct path path; | 569 | return sys_fchownat(AT_FDCWD, filename, user, group, 0); |
589 | int error; | 570 | } |
590 | 571 | ||
591 | error = user_lpath(filename, &path); | 572 | SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group) |
592 | if (error) | 573 | { |
593 | goto out; | 574 | return sys_fchownat(AT_FDCWD, filename, user, group, |
594 | error = mnt_want_write(path.mnt); | 575 | AT_SYMLINK_NOFOLLOW); |
595 | if (error) | ||
596 | goto out_release; | ||
597 | error = chown_common(&path, user, group); | ||
598 | mnt_drop_write(path.mnt); | ||
599 | out_release: | ||
600 | path_put(&path); | ||
601 | out: | ||
602 | return error; | ||
603 | } | 576 | } |
604 | 577 | ||
605 | SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group) | 578 | SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group) |
@@ -667,10 +640,9 @@ int open_check_o_direct(struct file *f) | |||
667 | return 0; | 640 | return 0; |
668 | } | 641 | } |
669 | 642 | ||
670 | static struct file *do_dentry_open(struct dentry *dentry, struct vfsmount *mnt, | 643 | static int do_dentry_open(struct file *f, |
671 | struct file *f, | 644 | int (*open)(struct inode *, struct file *), |
672 | int (*open)(struct inode *, struct file *), | 645 | const struct cred *cred) |
673 | const struct cred *cred) | ||
674 | { | 646 | { |
675 | static const struct file_operations empty_fops = {}; | 647 | static const struct file_operations empty_fops = {}; |
676 | struct inode *inode; | 648 | struct inode *inode; |
@@ -682,9 +654,9 @@ static struct file *do_dentry_open(struct dentry *dentry, struct vfsmount *mnt, | |||
682 | if (unlikely(f->f_flags & O_PATH)) | 654 | if (unlikely(f->f_flags & O_PATH)) |
683 | f->f_mode = FMODE_PATH; | 655 | f->f_mode = FMODE_PATH; |
684 | 656 | ||
685 | inode = dentry->d_inode; | 657 | inode = f->f_path.dentry->d_inode; |
686 | if (f->f_mode & FMODE_WRITE) { | 658 | if (f->f_mode & FMODE_WRITE) { |
687 | error = __get_file_write_access(inode, mnt); | 659 | error = __get_file_write_access(inode, f->f_path.mnt); |
688 | if (error) | 660 | if (error) |
689 | goto cleanup_file; | 661 | goto cleanup_file; |
690 | if (!special_file(inode->i_mode)) | 662 | if (!special_file(inode->i_mode)) |
@@ -692,14 +664,12 @@ static struct file *do_dentry_open(struct dentry *dentry, struct vfsmount *mnt, | |||
692 | } | 664 | } |
693 | 665 | ||
694 | f->f_mapping = inode->i_mapping; | 666 | f->f_mapping = inode->i_mapping; |
695 | f->f_path.dentry = dentry; | ||
696 | f->f_path.mnt = mnt; | ||
697 | f->f_pos = 0; | 667 | f->f_pos = 0; |
698 | file_sb_list_add(f, inode->i_sb); | 668 | file_sb_list_add(f, inode->i_sb); |
699 | 669 | ||
700 | if (unlikely(f->f_mode & FMODE_PATH)) { | 670 | if (unlikely(f->f_mode & FMODE_PATH)) { |
701 | f->f_op = &empty_fops; | 671 | f->f_op = &empty_fops; |
702 | return f; | 672 | return 0; |
703 | } | 673 | } |
704 | 674 | ||
705 | f->f_op = fops_get(inode->i_fop); | 675 | f->f_op = fops_get(inode->i_fop); |
@@ -726,10 +696,11 @@ static struct file *do_dentry_open(struct dentry *dentry, struct vfsmount *mnt, | |||
726 | 696 | ||
727 | file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping); | 697 | file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping); |
728 | 698 | ||
729 | return f; | 699 | return 0; |
730 | 700 | ||
731 | cleanup_all: | 701 | cleanup_all: |
732 | fops_put(f->f_op); | 702 | fops_put(f->f_op); |
703 | file_sb_list_del(f); | ||
733 | if (f->f_mode & FMODE_WRITE) { | 704 | if (f->f_mode & FMODE_WRITE) { |
734 | put_write_access(inode); | 705 | put_write_access(inode); |
735 | if (!special_file(inode->i_mode)) { | 706 | if (!special_file(inode->i_mode)) { |
@@ -740,118 +711,60 @@ cleanup_all: | |||
740 | * here, so just reset the state. | 711 | * here, so just reset the state. |
741 | */ | 712 | */ |
742 | file_reset_write(f); | 713 | file_reset_write(f); |
743 | mnt_drop_write(mnt); | 714 | mnt_drop_write(f->f_path.mnt); |
744 | } | 715 | } |
745 | } | 716 | } |
746 | file_sb_list_del(f); | ||
747 | f->f_path.dentry = NULL; | ||
748 | f->f_path.mnt = NULL; | ||
749 | cleanup_file: | 717 | cleanup_file: |
750 | dput(dentry); | 718 | path_put(&f->f_path); |
751 | mntput(mnt); | 719 | f->f_path.mnt = NULL; |
752 | return ERR_PTR(error); | 720 | f->f_path.dentry = NULL; |
753 | } | 721 | return error; |
754 | |||
755 | static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, | ||
756 | struct file *f, | ||
757 | int (*open)(struct inode *, struct file *), | ||
758 | const struct cred *cred) | ||
759 | { | ||
760 | struct file *res = do_dentry_open(dentry, mnt, f, open, cred); | ||
761 | if (!IS_ERR(res)) { | ||
762 | int error = open_check_o_direct(f); | ||
763 | if (error) { | ||
764 | fput(res); | ||
765 | res = ERR_PTR(error); | ||
766 | } | ||
767 | } else { | ||
768 | put_filp(f); | ||
769 | } | ||
770 | return res; | ||
771 | } | 722 | } |
772 | 723 | ||
773 | /** | 724 | /** |
774 | * lookup_instantiate_filp - instantiates the open intent filp | 725 | * finish_open - finish opening a file |
775 | * @nd: pointer to nameidata | 726 | * @od: opaque open data |
776 | * @dentry: pointer to dentry | 727 | * @dentry: pointer to dentry |
777 | * @open: open callback | 728 | * @open: open callback |
778 | * | 729 | * |
779 | * Helper for filesystems that want to use lookup open intents and pass back | 730 | * This can be used to finish opening a file passed to i_op->atomic_open(). |
780 | * a fully instantiated struct file to the caller. | 731 | * |
781 | * This function is meant to be called from within a filesystem's | ||
782 | * lookup method. | ||
783 | * Beware of calling it for non-regular files! Those ->open methods might block | ||
784 | * (e.g. in fifo_open), leaving you with parent locked (and in case of fifo, | ||
785 | * leading to a deadlock, as nobody can open that fifo anymore, because | ||
786 | * another process to open fifo will block on locked parent when doing lookup). | ||
787 | * Note that in case of error, nd->intent.open.file is destroyed, but the | ||
788 | * path information remains valid. | ||
789 | * If the open callback is set to NULL, then the standard f_op->open() | 732 | * If the open callback is set to NULL, then the standard f_op->open() |
790 | * filesystem callback is substituted. | 733 | * filesystem callback is substituted. |
791 | */ | 734 | */ |
792 | struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry, | 735 | int finish_open(struct file *file, struct dentry *dentry, |
793 | int (*open)(struct inode *, struct file *)) | 736 | int (*open)(struct inode *, struct file *), |
737 | int *opened) | ||
794 | { | 738 | { |
795 | const struct cred *cred = current_cred(); | 739 | int error; |
740 | BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */ | ||
796 | 741 | ||
797 | if (IS_ERR(nd->intent.open.file)) | 742 | mntget(file->f_path.mnt); |
798 | goto out; | 743 | file->f_path.dentry = dget(dentry); |
799 | if (IS_ERR(dentry)) | 744 | |
800 | goto out_err; | 745 | error = do_dentry_open(file, open, current_cred()); |
801 | nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->path.mnt), | 746 | if (!error) |
802 | nd->intent.open.file, | 747 | *opened |= FILE_OPENED; |
803 | open, cred); | 748 | |
804 | out: | 749 | return error; |
805 | return nd->intent.open.file; | ||
806 | out_err: | ||
807 | release_open_intent(nd); | ||
808 | nd->intent.open.file = ERR_CAST(dentry); | ||
809 | goto out; | ||
810 | } | 750 | } |
811 | EXPORT_SYMBOL_GPL(lookup_instantiate_filp); | 751 | EXPORT_SYMBOL(finish_open); |
812 | 752 | ||
813 | /** | 753 | /** |
814 | * nameidata_to_filp - convert a nameidata to an open filp. | 754 | * finish_no_open - finish ->atomic_open() without opening the file |
815 | * @nd: pointer to nameidata | ||
816 | * @flags: open flags | ||
817 | * | 755 | * |
818 | * Note that this function destroys the original nameidata | 756 | * @od: opaque open data |
757 | * @dentry: dentry or NULL (as returned from ->lookup()) | ||
758 | * | ||
759 | * This can be used to set the result of a successful lookup in ->atomic_open(). | ||
760 | * The filesystem's atomic_open() method shall return NULL after calling this. | ||
819 | */ | 761 | */ |
820 | struct file *nameidata_to_filp(struct nameidata *nd) | 762 | int finish_no_open(struct file *file, struct dentry *dentry) |
821 | { | 763 | { |
822 | const struct cred *cred = current_cred(); | 764 | file->f_path.dentry = dentry; |
823 | struct file *filp; | 765 | return 1; |
824 | |||
825 | /* Pick up the filp from the open intent */ | ||
826 | filp = nd->intent.open.file; | ||
827 | |||
828 | /* Has the filesystem initialised the file for us? */ | ||
829 | if (filp->f_path.dentry != NULL) { | ||
830 | nd->intent.open.file = NULL; | ||
831 | } else { | ||
832 | struct file *res; | ||
833 | |||
834 | path_get(&nd->path); | ||
835 | res = do_dentry_open(nd->path.dentry, nd->path.mnt, | ||
836 | filp, NULL, cred); | ||
837 | if (!IS_ERR(res)) { | ||
838 | int error; | ||
839 | |||
840 | nd->intent.open.file = NULL; | ||
841 | BUG_ON(res != filp); | ||
842 | |||
843 | error = open_check_o_direct(filp); | ||
844 | if (error) { | ||
845 | fput(filp); | ||
846 | filp = ERR_PTR(error); | ||
847 | } | ||
848 | } else { | ||
849 | /* Allow nd->intent.open.file to be recycled */ | ||
850 | filp = res; | ||
851 | } | ||
852 | } | ||
853 | return filp; | ||
854 | } | 766 | } |
767 | EXPORT_SYMBOL(finish_no_open); | ||
855 | 768 | ||
856 | /* | 769 | /* |
857 | * dentry_open() will have done dput(dentry) and mntput(mnt) if it returns an | 770 | * dentry_open() will have done dput(dentry) and mntput(mnt) if it returns an |
@@ -877,7 +790,20 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags, | |||
877 | } | 790 | } |
878 | 791 | ||
879 | f->f_flags = flags; | 792 | f->f_flags = flags; |
880 | return __dentry_open(dentry, mnt, f, NULL, cred); | 793 | f->f_path.mnt = mnt; |
794 | f->f_path.dentry = dentry; | ||
795 | error = do_dentry_open(f, NULL, cred); | ||
796 | if (!error) { | ||
797 | error = open_check_o_direct(f); | ||
798 | if (error) { | ||
799 | fput(f); | ||
800 | f = ERR_PTR(error); | ||
801 | } | ||
802 | } else { | ||
803 | put_filp(f); | ||
804 | f = ERR_PTR(error); | ||
805 | } | ||
806 | return f; | ||
881 | } | 807 | } |
882 | EXPORT_SYMBOL(dentry_open); | 808 | EXPORT_SYMBOL(dentry_open); |
883 | 809 | ||
diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c index bc49c975d501..4a3477949bca 100644 --- a/fs/openpromfs/inode.c +++ b/fs/openpromfs/inode.c | |||
@@ -170,13 +170,13 @@ static const struct file_operations openprom_operations = { | |||
170 | .llseek = generic_file_llseek, | 170 | .llseek = generic_file_llseek, |
171 | }; | 171 | }; |
172 | 172 | ||
173 | static struct dentry *openpromfs_lookup(struct inode *, struct dentry *, struct nameidata *); | 173 | static struct dentry *openpromfs_lookup(struct inode *, struct dentry *, unsigned int); |
174 | 174 | ||
175 | static const struct inode_operations openprom_inode_operations = { | 175 | static const struct inode_operations openprom_inode_operations = { |
176 | .lookup = openpromfs_lookup, | 176 | .lookup = openpromfs_lookup, |
177 | }; | 177 | }; |
178 | 178 | ||
179 | static struct dentry *openpromfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | 179 | static struct dentry *openpromfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) |
180 | { | 180 | { |
181 | struct op_inode_info *ent_oi, *oi = OP_I(dir); | 181 | struct op_inode_info *ent_oi, *oi = OP_I(dir); |
182 | struct device_node *dp, *child; | 182 | struct device_node *dp, *child; |
diff --git a/fs/pnode.c b/fs/pnode.c index bed378db0758..3e000a51ac0d 100644 --- a/fs/pnode.c +++ b/fs/pnode.c | |||
@@ -237,8 +237,9 @@ int propagate_mnt(struct mount *dest_mnt, struct dentry *dest_dentry, | |||
237 | 237 | ||
238 | source = get_source(m, prev_dest_mnt, prev_src_mnt, &type); | 238 | source = get_source(m, prev_dest_mnt, prev_src_mnt, &type); |
239 | 239 | ||
240 | if (!(child = copy_tree(source, source->mnt.mnt_root, type))) { | 240 | child = copy_tree(source, source->mnt.mnt_root, type); |
241 | ret = -ENOMEM; | 241 | if (IS_ERR(child)) { |
242 | ret = PTR_ERR(child); | ||
242 | list_splice(tree_list, tmp_list.prev); | 243 | list_splice(tree_list, tmp_list.prev); |
243 | goto out; | 244 | goto out; |
244 | } | 245 | } |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 437195f204e1..2772208338f8 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -1427,16 +1427,19 @@ static int proc_exe_link(struct dentry *dentry, struct path *exe_path) | |||
1427 | static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd) | 1427 | static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd) |
1428 | { | 1428 | { |
1429 | struct inode *inode = dentry->d_inode; | 1429 | struct inode *inode = dentry->d_inode; |
1430 | struct path path; | ||
1430 | int error = -EACCES; | 1431 | int error = -EACCES; |
1431 | 1432 | ||
1432 | /* We don't need a base pointer in the /proc filesystem */ | ||
1433 | path_put(&nd->path); | ||
1434 | |||
1435 | /* Are we allowed to snoop on the tasks file descriptors? */ | 1433 | /* Are we allowed to snoop on the tasks file descriptors? */ |
1436 | if (!proc_fd_access_allowed(inode)) | 1434 | if (!proc_fd_access_allowed(inode)) |
1437 | goto out; | 1435 | goto out; |
1438 | 1436 | ||
1439 | error = PROC_I(inode)->op.proc_get_link(dentry, &nd->path); | 1437 | error = PROC_I(inode)->op.proc_get_link(dentry, &path); |
1438 | if (error) | ||
1439 | goto out; | ||
1440 | |||
1441 | nd_jump_link(nd, &path); | ||
1442 | return NULL; | ||
1440 | out: | 1443 | out: |
1441 | return ERR_PTR(error); | 1444 | return ERR_PTR(error); |
1442 | } | 1445 | } |
@@ -1601,13 +1604,13 @@ int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | |||
1601 | * made this apply to all per process world readable and executable | 1604 | * made this apply to all per process world readable and executable |
1602 | * directories. | 1605 | * directories. |
1603 | */ | 1606 | */ |
1604 | int pid_revalidate(struct dentry *dentry, struct nameidata *nd) | 1607 | int pid_revalidate(struct dentry *dentry, unsigned int flags) |
1605 | { | 1608 | { |
1606 | struct inode *inode; | 1609 | struct inode *inode; |
1607 | struct task_struct *task; | 1610 | struct task_struct *task; |
1608 | const struct cred *cred; | 1611 | const struct cred *cred; |
1609 | 1612 | ||
1610 | if (nd && nd->flags & LOOKUP_RCU) | 1613 | if (flags & LOOKUP_RCU) |
1611 | return -ECHILD; | 1614 | return -ECHILD; |
1612 | 1615 | ||
1613 | inode = dentry->d_inode; | 1616 | inode = dentry->d_inode; |
@@ -1781,7 +1784,7 @@ static int proc_fd_link(struct dentry *dentry, struct path *path) | |||
1781 | return proc_fd_info(dentry->d_inode, path, NULL); | 1784 | return proc_fd_info(dentry->d_inode, path, NULL); |
1782 | } | 1785 | } |
1783 | 1786 | ||
1784 | static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) | 1787 | static int tid_fd_revalidate(struct dentry *dentry, unsigned int flags) |
1785 | { | 1788 | { |
1786 | struct inode *inode; | 1789 | struct inode *inode; |
1787 | struct task_struct *task; | 1790 | struct task_struct *task; |
@@ -1789,7 +1792,7 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
1789 | struct files_struct *files; | 1792 | struct files_struct *files; |
1790 | const struct cred *cred; | 1793 | const struct cred *cred; |
1791 | 1794 | ||
1792 | if (nd && nd->flags & LOOKUP_RCU) | 1795 | if (flags & LOOKUP_RCU) |
1793 | return -ECHILD; | 1796 | return -ECHILD; |
1794 | 1797 | ||
1795 | inode = dentry->d_inode; | 1798 | inode = dentry->d_inode; |
@@ -1868,7 +1871,7 @@ static struct dentry *proc_fd_instantiate(struct inode *dir, | |||
1868 | d_set_d_op(dentry, &tid_fd_dentry_operations); | 1871 | d_set_d_op(dentry, &tid_fd_dentry_operations); |
1869 | d_add(dentry, inode); | 1872 | d_add(dentry, inode); |
1870 | /* Close the race of the process dying before we return the dentry */ | 1873 | /* Close the race of the process dying before we return the dentry */ |
1871 | if (tid_fd_revalidate(dentry, NULL)) | 1874 | if (tid_fd_revalidate(dentry, 0)) |
1872 | error = NULL; | 1875 | error = NULL; |
1873 | 1876 | ||
1874 | out: | 1877 | out: |
@@ -1956,7 +1959,7 @@ out_no_task: | |||
1956 | } | 1959 | } |
1957 | 1960 | ||
1958 | static struct dentry *proc_lookupfd(struct inode *dir, struct dentry *dentry, | 1961 | static struct dentry *proc_lookupfd(struct inode *dir, struct dentry *dentry, |
1959 | struct nameidata *nd) | 1962 | unsigned int flags) |
1960 | { | 1963 | { |
1961 | return proc_lookupfd_common(dir, dentry, proc_fd_instantiate); | 1964 | return proc_lookupfd_common(dir, dentry, proc_fd_instantiate); |
1962 | } | 1965 | } |
@@ -2003,7 +2006,7 @@ static int dname_to_vma_addr(struct dentry *dentry, | |||
2003 | return 0; | 2006 | return 0; |
2004 | } | 2007 | } |
2005 | 2008 | ||
2006 | static int map_files_d_revalidate(struct dentry *dentry, struct nameidata *nd) | 2009 | static int map_files_d_revalidate(struct dentry *dentry, unsigned int flags) |
2007 | { | 2010 | { |
2008 | unsigned long vm_start, vm_end; | 2011 | unsigned long vm_start, vm_end; |
2009 | bool exact_vma_exists = false; | 2012 | bool exact_vma_exists = false; |
@@ -2013,7 +2016,7 @@ static int map_files_d_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
2013 | struct inode *inode; | 2016 | struct inode *inode; |
2014 | int status = 0; | 2017 | int status = 0; |
2015 | 2018 | ||
2016 | if (nd && nd->flags & LOOKUP_RCU) | 2019 | if (flags & LOOKUP_RCU) |
2017 | return -ECHILD; | 2020 | return -ECHILD; |
2018 | 2021 | ||
2019 | if (!capable(CAP_SYS_ADMIN)) { | 2022 | if (!capable(CAP_SYS_ADMIN)) { |
@@ -2145,7 +2148,7 @@ proc_map_files_instantiate(struct inode *dir, struct dentry *dentry, | |||
2145 | } | 2148 | } |
2146 | 2149 | ||
2147 | static struct dentry *proc_map_files_lookup(struct inode *dir, | 2150 | static struct dentry *proc_map_files_lookup(struct inode *dir, |
2148 | struct dentry *dentry, struct nameidata *nd) | 2151 | struct dentry *dentry, unsigned int flags) |
2149 | { | 2152 | { |
2150 | unsigned long vm_start, vm_end; | 2153 | unsigned long vm_start, vm_end; |
2151 | struct vm_area_struct *vma; | 2154 | struct vm_area_struct *vma; |
@@ -2371,7 +2374,7 @@ static struct dentry *proc_fdinfo_instantiate(struct inode *dir, | |||
2371 | d_set_d_op(dentry, &tid_fd_dentry_operations); | 2374 | d_set_d_op(dentry, &tid_fd_dentry_operations); |
2372 | d_add(dentry, inode); | 2375 | d_add(dentry, inode); |
2373 | /* Close the race of the process dying before we return the dentry */ | 2376 | /* Close the race of the process dying before we return the dentry */ |
2374 | if (tid_fd_revalidate(dentry, NULL)) | 2377 | if (tid_fd_revalidate(dentry, 0)) |
2375 | error = NULL; | 2378 | error = NULL; |
2376 | 2379 | ||
2377 | out: | 2380 | out: |
@@ -2380,7 +2383,7 @@ static struct dentry *proc_fdinfo_instantiate(struct inode *dir, | |||
2380 | 2383 | ||
2381 | static struct dentry *proc_lookupfdinfo(struct inode *dir, | 2384 | static struct dentry *proc_lookupfdinfo(struct inode *dir, |
2382 | struct dentry *dentry, | 2385 | struct dentry *dentry, |
2383 | struct nameidata *nd) | 2386 | unsigned int flags) |
2384 | { | 2387 | { |
2385 | return proc_lookupfd_common(dir, dentry, proc_fdinfo_instantiate); | 2388 | return proc_lookupfd_common(dir, dentry, proc_fdinfo_instantiate); |
2386 | } | 2389 | } |
@@ -2430,7 +2433,7 @@ static struct dentry *proc_pident_instantiate(struct inode *dir, | |||
2430 | d_set_d_op(dentry, &pid_dentry_operations); | 2433 | d_set_d_op(dentry, &pid_dentry_operations); |
2431 | d_add(dentry, inode); | 2434 | d_add(dentry, inode); |
2432 | /* Close the race of the process dying before we return the dentry */ | 2435 | /* Close the race of the process dying before we return the dentry */ |
2433 | if (pid_revalidate(dentry, NULL)) | 2436 | if (pid_revalidate(dentry, 0)) |
2434 | error = NULL; | 2437 | error = NULL; |
2435 | out: | 2438 | out: |
2436 | return error; | 2439 | return error; |
@@ -2630,7 +2633,7 @@ static const struct file_operations proc_attr_dir_operations = { | |||
2630 | }; | 2633 | }; |
2631 | 2634 | ||
2632 | static struct dentry *proc_attr_dir_lookup(struct inode *dir, | 2635 | static struct dentry *proc_attr_dir_lookup(struct inode *dir, |
2633 | struct dentry *dentry, struct nameidata *nd) | 2636 | struct dentry *dentry, unsigned int flags) |
2634 | { | 2637 | { |
2635 | return proc_pident_lookup(dir, dentry, | 2638 | return proc_pident_lookup(dir, dentry, |
2636 | attr_dir_stuff, ARRAY_SIZE(attr_dir_stuff)); | 2639 | attr_dir_stuff, ARRAY_SIZE(attr_dir_stuff)); |
@@ -3114,7 +3117,8 @@ static const struct file_operations proc_tgid_base_operations = { | |||
3114 | .llseek = default_llseek, | 3117 | .llseek = default_llseek, |
3115 | }; | 3118 | }; |
3116 | 3119 | ||
3117 | static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){ | 3120 | static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) |
3121 | { | ||
3118 | return proc_pident_lookup(dir, dentry, | 3122 | return proc_pident_lookup(dir, dentry, |
3119 | tgid_base_stuff, ARRAY_SIZE(tgid_base_stuff)); | 3123 | tgid_base_stuff, ARRAY_SIZE(tgid_base_stuff)); |
3120 | } | 3124 | } |
@@ -3237,13 +3241,13 @@ static struct dentry *proc_pid_instantiate(struct inode *dir, | |||
3237 | 3241 | ||
3238 | d_add(dentry, inode); | 3242 | d_add(dentry, inode); |
3239 | /* Close the race of the process dying before we return the dentry */ | 3243 | /* Close the race of the process dying before we return the dentry */ |
3240 | if (pid_revalidate(dentry, NULL)) | 3244 | if (pid_revalidate(dentry, 0)) |
3241 | error = NULL; | 3245 | error = NULL; |
3242 | out: | 3246 | out: |
3243 | return error; | 3247 | return error; |
3244 | } | 3248 | } |
3245 | 3249 | ||
3246 | struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) | 3250 | struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags) |
3247 | { | 3251 | { |
3248 | struct dentry *result; | 3252 | struct dentry *result; |
3249 | struct task_struct *task; | 3253 | struct task_struct *task; |
@@ -3470,7 +3474,8 @@ static int proc_tid_base_readdir(struct file * filp, | |||
3470 | tid_base_stuff,ARRAY_SIZE(tid_base_stuff)); | 3474 | tid_base_stuff,ARRAY_SIZE(tid_base_stuff)); |
3471 | } | 3475 | } |
3472 | 3476 | ||
3473 | static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){ | 3477 | static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) |
3478 | { | ||
3474 | return proc_pident_lookup(dir, dentry, | 3479 | return proc_pident_lookup(dir, dentry, |
3475 | tid_base_stuff, ARRAY_SIZE(tid_base_stuff)); | 3480 | tid_base_stuff, ARRAY_SIZE(tid_base_stuff)); |
3476 | } | 3481 | } |
@@ -3508,13 +3513,13 @@ static struct dentry *proc_task_instantiate(struct inode *dir, | |||
3508 | 3513 | ||
3509 | d_add(dentry, inode); | 3514 | d_add(dentry, inode); |
3510 | /* Close the race of the process dying before we return the dentry */ | 3515 | /* Close the race of the process dying before we return the dentry */ |
3511 | if (pid_revalidate(dentry, NULL)) | 3516 | if (pid_revalidate(dentry, 0)) |
3512 | error = NULL; | 3517 | error = NULL; |
3513 | out: | 3518 | out: |
3514 | return error; | 3519 | return error; |
3515 | } | 3520 | } |
3516 | 3521 | ||
3517 | static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) | 3522 | static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags) |
3518 | { | 3523 | { |
3519 | struct dentry *result = ERR_PTR(-ENOENT); | 3524 | struct dentry *result = ERR_PTR(-ENOENT); |
3520 | struct task_struct *task; | 3525 | struct task_struct *task; |
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 2edf34f2eb61..b3647fe6a608 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c | |||
@@ -446,7 +446,7 @@ out_unlock: | |||
446 | } | 446 | } |
447 | 447 | ||
448 | struct dentry *proc_lookup(struct inode *dir, struct dentry *dentry, | 448 | struct dentry *proc_lookup(struct inode *dir, struct dentry *dentry, |
449 | struct nameidata *nd) | 449 | unsigned int flags) |
450 | { | 450 | { |
451 | return proc_lookup_de(PDE(dir), dir, dentry); | 451 | return proc_lookup_de(PDE(dir), dir, dentry); |
452 | } | 452 | } |
diff --git a/fs/proc/internal.h b/fs/proc/internal.h index eca4aca5b6e2..e1167a1c9126 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h | |||
@@ -106,7 +106,7 @@ void pde_users_dec(struct proc_dir_entry *pde); | |||
106 | 106 | ||
107 | extern spinlock_t proc_subdir_lock; | 107 | extern spinlock_t proc_subdir_lock; |
108 | 108 | ||
109 | struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *); | 109 | struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, unsigned int); |
110 | int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir); | 110 | int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir); |
111 | unsigned long task_vsize(struct mm_struct *); | 111 | unsigned long task_vsize(struct mm_struct *); |
112 | unsigned long task_statm(struct mm_struct *, | 112 | unsigned long task_statm(struct mm_struct *, |
@@ -132,7 +132,7 @@ int proc_remount(struct super_block *sb, int *flags, char *data); | |||
132 | * of the /proc/<pid> subdirectories. | 132 | * of the /proc/<pid> subdirectories. |
133 | */ | 133 | */ |
134 | int proc_readdir(struct file *, void *, filldir_t); | 134 | int proc_readdir(struct file *, void *, filldir_t); |
135 | struct dentry *proc_lookup(struct inode *, struct dentry *, struct nameidata *); | 135 | struct dentry *proc_lookup(struct inode *, struct dentry *, unsigned int); |
136 | 136 | ||
137 | 137 | ||
138 | 138 | ||
@@ -142,7 +142,7 @@ typedef struct dentry *instantiate_t(struct inode *, struct dentry *, | |||
142 | int proc_fill_cache(struct file *filp, void *dirent, filldir_t filldir, | 142 | int proc_fill_cache(struct file *filp, void *dirent, filldir_t filldir, |
143 | const char *name, int len, | 143 | const char *name, int len, |
144 | instantiate_t instantiate, struct task_struct *task, const void *ptr); | 144 | instantiate_t instantiate, struct task_struct *task, const void *ptr); |
145 | int pid_revalidate(struct dentry *dentry, struct nameidata *nd); | 145 | int pid_revalidate(struct dentry *dentry, unsigned int flags); |
146 | struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task); | 146 | struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task); |
147 | extern const struct dentry_operations pid_dentry_operations; | 147 | extern const struct dentry_operations pid_dentry_operations; |
148 | int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); | 148 | int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); |
diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c index 0d9e23a39e49..b178ed733c36 100644 --- a/fs/proc/namespaces.c +++ b/fs/proc/namespaces.c | |||
@@ -56,7 +56,7 @@ static struct dentry *proc_ns_instantiate(struct inode *dir, | |||
56 | d_set_d_op(dentry, &pid_dentry_operations); | 56 | d_set_d_op(dentry, &pid_dentry_operations); |
57 | d_add(dentry, inode); | 57 | d_add(dentry, inode); |
58 | /* Close the race of the process dying before we return the dentry */ | 58 | /* Close the race of the process dying before we return the dentry */ |
59 | if (pid_revalidate(dentry, NULL)) | 59 | if (pid_revalidate(dentry, 0)) |
60 | error = NULL; | 60 | error = NULL; |
61 | out: | 61 | out: |
62 | return error; | 62 | return error; |
@@ -140,7 +140,7 @@ const struct file_operations proc_ns_dir_operations = { | |||
140 | }; | 140 | }; |
141 | 141 | ||
142 | static struct dentry *proc_ns_dir_lookup(struct inode *dir, | 142 | static struct dentry *proc_ns_dir_lookup(struct inode *dir, |
143 | struct dentry *dentry, struct nameidata *nd) | 143 | struct dentry *dentry, unsigned int flags) |
144 | { | 144 | { |
145 | struct dentry *error; | 145 | struct dentry *error; |
146 | struct task_struct *task = get_proc_task(dir); | 146 | struct task_struct *task = get_proc_task(dir); |
diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c index 06e1cc17caf6..fe72cd073dea 100644 --- a/fs/proc/proc_net.c +++ b/fs/proc/proc_net.c | |||
@@ -119,7 +119,7 @@ static struct net *get_proc_task_net(struct inode *dir) | |||
119 | } | 119 | } |
120 | 120 | ||
121 | static struct dentry *proc_tgid_net_lookup(struct inode *dir, | 121 | static struct dentry *proc_tgid_net_lookup(struct inode *dir, |
122 | struct dentry *dentry, struct nameidata *nd) | 122 | struct dentry *dentry, unsigned int flags) |
123 | { | 123 | { |
124 | struct dentry *de; | 124 | struct dentry *de; |
125 | struct net *net; | 125 | struct net *net; |
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 3476bca8f7af..dfafeb2b05a0 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c | |||
@@ -433,7 +433,7 @@ static struct ctl_table_header *grab_header(struct inode *inode) | |||
433 | } | 433 | } |
434 | 434 | ||
435 | static struct dentry *proc_sys_lookup(struct inode *dir, struct dentry *dentry, | 435 | static struct dentry *proc_sys_lookup(struct inode *dir, struct dentry *dentry, |
436 | struct nameidata *nd) | 436 | unsigned int flags) |
437 | { | 437 | { |
438 | struct ctl_table_header *head = grab_header(dir); | 438 | struct ctl_table_header *head = grab_header(dir); |
439 | struct ctl_table_header *h = NULL; | 439 | struct ctl_table_header *h = NULL; |
@@ -794,9 +794,9 @@ static const struct inode_operations proc_sys_dir_operations = { | |||
794 | .getattr = proc_sys_getattr, | 794 | .getattr = proc_sys_getattr, |
795 | }; | 795 | }; |
796 | 796 | ||
797 | static int proc_sys_revalidate(struct dentry *dentry, struct nameidata *nd) | 797 | static int proc_sys_revalidate(struct dentry *dentry, unsigned int flags) |
798 | { | 798 | { |
799 | if (nd->flags & LOOKUP_RCU) | 799 | if (flags & LOOKUP_RCU) |
800 | return -ECHILD; | 800 | return -ECHILD; |
801 | return !PROC_I(dentry->d_inode)->sysctl->unregistering; | 801 | return !PROC_I(dentry->d_inode)->sysctl->unregistering; |
802 | } | 802 | } |
diff --git a/fs/proc/root.c b/fs/proc/root.c index 7c30fce037c0..9a2d9fd7cadd 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c | |||
@@ -111,7 +111,7 @@ static struct dentry *proc_mount(struct file_system_type *fs_type, | |||
111 | options = data; | 111 | options = data; |
112 | } | 112 | } |
113 | 113 | ||
114 | sb = sget(fs_type, proc_test_super, proc_set_super, ns); | 114 | sb = sget(fs_type, proc_test_super, proc_set_super, flags, ns); |
115 | if (IS_ERR(sb)) | 115 | if (IS_ERR(sb)) |
116 | return ERR_CAST(sb); | 116 | return ERR_CAST(sb); |
117 | 117 | ||
@@ -121,7 +121,6 @@ static struct dentry *proc_mount(struct file_system_type *fs_type, | |||
121 | } | 121 | } |
122 | 122 | ||
123 | if (!sb->s_root) { | 123 | if (!sb->s_root) { |
124 | sb->s_flags = flags; | ||
125 | err = proc_fill_super(sb); | 124 | err = proc_fill_super(sb); |
126 | if (err) { | 125 | if (err) { |
127 | deactivate_locked_super(sb); | 126 | deactivate_locked_super(sb); |
@@ -200,13 +199,12 @@ static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, struct | |||
200 | return 0; | 199 | return 0; |
201 | } | 200 | } |
202 | 201 | ||
203 | static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd) | 202 | static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry, unsigned int flags) |
204 | { | 203 | { |
205 | if (!proc_lookup(dir, dentry, nd)) { | 204 | if (!proc_lookup(dir, dentry, flags)) |
206 | return NULL; | 205 | return NULL; |
207 | } | ||
208 | 206 | ||
209 | return proc_pid_lookup(dir, dentry, nd); | 207 | return proc_pid_lookup(dir, dentry, flags); |
210 | } | 208 | } |
211 | 209 | ||
212 | static int proc_root_readdir(struct file * filp, | 210 | static int proc_root_readdir(struct file * filp, |
diff --git a/fs/proc_namespace.c b/fs/proc_namespace.c index 5e289a7cbad1..5fe34c355e85 100644 --- a/fs/proc_namespace.c +++ b/fs/proc_namespace.c | |||
@@ -17,7 +17,7 @@ | |||
17 | 17 | ||
18 | static unsigned mounts_poll(struct file *file, poll_table *wait) | 18 | static unsigned mounts_poll(struct file *file, poll_table *wait) |
19 | { | 19 | { |
20 | struct proc_mounts *p = file->private_data; | 20 | struct proc_mounts *p = proc_mounts(file->private_data); |
21 | struct mnt_namespace *ns = p->ns; | 21 | struct mnt_namespace *ns = p->ns; |
22 | unsigned res = POLLIN | POLLRDNORM; | 22 | unsigned res = POLLIN | POLLRDNORM; |
23 | 23 | ||
@@ -121,7 +121,7 @@ out: | |||
121 | 121 | ||
122 | static int show_mountinfo(struct seq_file *m, struct vfsmount *mnt) | 122 | static int show_mountinfo(struct seq_file *m, struct vfsmount *mnt) |
123 | { | 123 | { |
124 | struct proc_mounts *p = m->private; | 124 | struct proc_mounts *p = proc_mounts(m); |
125 | struct mount *r = real_mount(mnt); | 125 | struct mount *r = real_mount(mnt); |
126 | struct super_block *sb = mnt->mnt_sb; | 126 | struct super_block *sb = mnt->mnt_sb; |
127 | struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt }; | 127 | struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt }; |
@@ -268,7 +268,6 @@ static int mounts_open_common(struct inode *inode, struct file *file, | |||
268 | if (ret) | 268 | if (ret) |
269 | goto err_free; | 269 | goto err_free; |
270 | 270 | ||
271 | p->m.private = p; | ||
272 | p->ns = ns; | 271 | p->ns = ns; |
273 | p->root = root; | 272 | p->root = root; |
274 | p->m.poll_event = ns->event; | 273 | p->m.poll_event = ns->event; |
@@ -288,7 +287,7 @@ static int mounts_open_common(struct inode *inode, struct file *file, | |||
288 | 287 | ||
289 | static int mounts_release(struct inode *inode, struct file *file) | 288 | static int mounts_release(struct inode *inode, struct file *file) |
290 | { | 289 | { |
291 | struct proc_mounts *p = file->private_data; | 290 | struct proc_mounts *p = proc_mounts(file->private_data); |
292 | path_put(&p->root); | 291 | path_put(&p->root); |
293 | put_mnt_ns(p->ns); | 292 | put_mnt_ns(p->ns); |
294 | return seq_release(inode, file); | 293 | return seq_release(inode, file); |
diff --git a/fs/qnx4/namei.c b/fs/qnx4/namei.c index a512c0b30e8e..d024505ba007 100644 --- a/fs/qnx4/namei.c +++ b/fs/qnx4/namei.c | |||
@@ -95,7 +95,7 @@ static struct buffer_head *qnx4_find_entry(int len, struct inode *dir, | |||
95 | return NULL; | 95 | return NULL; |
96 | } | 96 | } |
97 | 97 | ||
98 | struct dentry * qnx4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | 98 | struct dentry * qnx4_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) |
99 | { | 99 | { |
100 | int ino; | 100 | int ino; |
101 | struct qnx4_inode_entry *de; | 101 | struct qnx4_inode_entry *de; |
diff --git a/fs/qnx4/qnx4.h b/fs/qnx4/qnx4.h index 244d4620189b..34e2d329c97e 100644 --- a/fs/qnx4/qnx4.h +++ b/fs/qnx4/qnx4.h | |||
@@ -23,7 +23,7 @@ struct qnx4_inode_info { | |||
23 | }; | 23 | }; |
24 | 24 | ||
25 | extern struct inode *qnx4_iget(struct super_block *, unsigned long); | 25 | extern struct inode *qnx4_iget(struct super_block *, unsigned long); |
26 | extern struct dentry *qnx4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd); | 26 | extern struct dentry *qnx4_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags); |
27 | extern unsigned long qnx4_count_free_blocks(struct super_block *sb); | 27 | extern unsigned long qnx4_count_free_blocks(struct super_block *sb); |
28 | extern unsigned long qnx4_block_map(struct inode *inode, long iblock); | 28 | extern unsigned long qnx4_block_map(struct inode *inode, long iblock); |
29 | 29 | ||
diff --git a/fs/qnx6/inode.c b/fs/qnx6/inode.c index e44012dc5645..2049c814bda4 100644 --- a/fs/qnx6/inode.c +++ b/fs/qnx6/inode.c | |||
@@ -622,7 +622,6 @@ static struct inode *qnx6_alloc_inode(struct super_block *sb) | |||
622 | static void qnx6_i_callback(struct rcu_head *head) | 622 | static void qnx6_i_callback(struct rcu_head *head) |
623 | { | 623 | { |
624 | struct inode *inode = container_of(head, struct inode, i_rcu); | 624 | struct inode *inode = container_of(head, struct inode, i_rcu); |
625 | INIT_LIST_HEAD(&inode->i_dentry); | ||
626 | kmem_cache_free(qnx6_inode_cachep, QNX6_I(inode)); | 625 | kmem_cache_free(qnx6_inode_cachep, QNX6_I(inode)); |
627 | } | 626 | } |
628 | 627 | ||
diff --git a/fs/qnx6/namei.c b/fs/qnx6/namei.c index 8a97289e04ad..0561326a94f5 100644 --- a/fs/qnx6/namei.c +++ b/fs/qnx6/namei.c | |||
@@ -13,7 +13,7 @@ | |||
13 | #include "qnx6.h" | 13 | #include "qnx6.h" |
14 | 14 | ||
15 | struct dentry *qnx6_lookup(struct inode *dir, struct dentry *dentry, | 15 | struct dentry *qnx6_lookup(struct inode *dir, struct dentry *dentry, |
16 | struct nameidata *nd) | 16 | unsigned int flags) |
17 | { | 17 | { |
18 | unsigned ino; | 18 | unsigned ino; |
19 | struct page *page; | 19 | struct page *page; |
diff --git a/fs/qnx6/qnx6.h b/fs/qnx6/qnx6.h index 6c5e02a0b6a8..b00fcc960d37 100644 --- a/fs/qnx6/qnx6.h +++ b/fs/qnx6/qnx6.h | |||
@@ -45,7 +45,7 @@ struct qnx6_inode_info { | |||
45 | 45 | ||
46 | extern struct inode *qnx6_iget(struct super_block *sb, unsigned ino); | 46 | extern struct inode *qnx6_iget(struct super_block *sb, unsigned ino); |
47 | extern struct dentry *qnx6_lookup(struct inode *dir, struct dentry *dentry, | 47 | extern struct dentry *qnx6_lookup(struct inode *dir, struct dentry *dentry, |
48 | struct nameidata *nd); | 48 | unsigned int flags); |
49 | 49 | ||
50 | #ifdef CONFIG_QNX6FS_DEBUG | 50 | #ifdef CONFIG_QNX6FS_DEBUG |
51 | extern void qnx6_superblock_debug(struct qnx6_super_block *, | 51 | extern void qnx6_superblock_debug(struct qnx6_super_block *, |
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c index fbb0b478a346..d5378d028589 100644 --- a/fs/ramfs/file-nommu.c +++ b/fs/ramfs/file-nommu.c | |||
@@ -110,6 +110,7 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) | |||
110 | 110 | ||
111 | /* prevent the page from being discarded on memory pressure */ | 111 | /* prevent the page from being discarded on memory pressure */ |
112 | SetPageDirty(page); | 112 | SetPageDirty(page); |
113 | SetPageUptodate(page); | ||
113 | 114 | ||
114 | unlock_page(page); | 115 | unlock_page(page); |
115 | put_page(page); | 116 | put_page(page); |
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index a1fdabe21dec..eab8c09d3801 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c | |||
@@ -114,7 +114,7 @@ static int ramfs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) | |||
114 | return retval; | 114 | return retval; |
115 | } | 115 | } |
116 | 116 | ||
117 | static int ramfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, struct nameidata *nd) | 117 | static int ramfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool excl) |
118 | { | 118 | { |
119 | return ramfs_mknod(dir, dentry, mode | S_IFREG, 0); | 119 | return ramfs_mknod(dir, dentry, mode | S_IFREG, 0); |
120 | } | 120 | } |
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index 84e8a69cee9d..3916be1a330b 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c | |||
@@ -322,7 +322,7 @@ static int reiserfs_find_entry(struct inode *dir, const char *name, int namelen, | |||
322 | } | 322 | } |
323 | 323 | ||
324 | static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry, | 324 | static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry, |
325 | struct nameidata *nd) | 325 | unsigned int flags) |
326 | { | 326 | { |
327 | int retval; | 327 | int retval; |
328 | int lock_depth; | 328 | int lock_depth; |
@@ -573,7 +573,7 @@ static int new_inode_init(struct inode *inode, struct inode *dir, umode_t mode) | |||
573 | } | 573 | } |
574 | 574 | ||
575 | static int reiserfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 575 | static int reiserfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
576 | struct nameidata *nd) | 576 | bool excl) |
577 | { | 577 | { |
578 | int retval; | 578 | int retval; |
579 | struct inode *inode; | 579 | struct inode *inode; |
diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c index 2c1ade692cc8..e60e87035bb3 100644 --- a/fs/reiserfs/procfs.c +++ b/fs/reiserfs/procfs.c | |||
@@ -403,7 +403,7 @@ static void *r_start(struct seq_file *m, loff_t * pos) | |||
403 | if (l) | 403 | if (l) |
404 | return NULL; | 404 | return NULL; |
405 | 405 | ||
406 | if (IS_ERR(sget(&reiserfs_fs_type, test_sb, set_sb, s))) | 406 | if (IS_ERR(sget(&reiserfs_fs_type, test_sb, set_sb, 0, s))) |
407 | return NULL; | 407 | return NULL; |
408 | 408 | ||
409 | up_write(&s->s_umount); | 409 | up_write(&s->s_umount); |
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 46fc1c20a6b1..d319963aeb11 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
@@ -62,7 +62,7 @@ | |||
62 | static int xattr_create(struct inode *dir, struct dentry *dentry, int mode) | 62 | static int xattr_create(struct inode *dir, struct dentry *dentry, int mode) |
63 | { | 63 | { |
64 | BUG_ON(!mutex_is_locked(&dir->i_mutex)); | 64 | BUG_ON(!mutex_is_locked(&dir->i_mutex)); |
65 | return dir->i_op->create(dir, dentry, mode, NULL); | 65 | return dir->i_op->create(dir, dentry, mode, true); |
66 | } | 66 | } |
67 | #endif | 67 | #endif |
68 | 68 | ||
@@ -942,7 +942,7 @@ int reiserfs_permission(struct inode *inode, int mask) | |||
942 | return generic_permission(inode, mask); | 942 | return generic_permission(inode, mask); |
943 | } | 943 | } |
944 | 944 | ||
945 | static int xattr_hide_revalidate(struct dentry *dentry, struct nameidata *nd) | 945 | static int xattr_hide_revalidate(struct dentry *dentry, unsigned int flags) |
946 | { | 946 | { |
947 | return -EPERM; | 947 | return -EPERM; |
948 | } | 948 | } |
diff --git a/fs/romfs/super.c b/fs/romfs/super.c index e64f6b5f7ae5..77c5f2173983 100644 --- a/fs/romfs/super.c +++ b/fs/romfs/super.c | |||
@@ -210,7 +210,7 @@ out: | |||
210 | * look up an entry in a directory | 210 | * look up an entry in a directory |
211 | */ | 211 | */ |
212 | static struct dentry *romfs_lookup(struct inode *dir, struct dentry *dentry, | 212 | static struct dentry *romfs_lookup(struct inode *dir, struct dentry *dentry, |
213 | struct nameidata *nd) | 213 | unsigned int flags) |
214 | { | 214 | { |
215 | unsigned long offset, maxoff; | 215 | unsigned long offset, maxoff; |
216 | struct inode *inode; | 216 | struct inode *inode; |
diff --git a/fs/splice.c b/fs/splice.c index c9f1318a3b82..7bf08fa22ec9 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -273,13 +273,16 @@ void spd_release_page(struct splice_pipe_desc *spd, unsigned int i) | |||
273 | * Check if we need to grow the arrays holding pages and partial page | 273 | * Check if we need to grow the arrays holding pages and partial page |
274 | * descriptions. | 274 | * descriptions. |
275 | */ | 275 | */ |
276 | int splice_grow_spd(struct pipe_inode_info *pipe, struct splice_pipe_desc *spd) | 276 | int splice_grow_spd(const struct pipe_inode_info *pipe, struct splice_pipe_desc *spd) |
277 | { | 277 | { |
278 | if (pipe->buffers <= PIPE_DEF_BUFFERS) | 278 | unsigned int buffers = ACCESS_ONCE(pipe->buffers); |
279 | |||
280 | spd->nr_pages_max = buffers; | ||
281 | if (buffers <= PIPE_DEF_BUFFERS) | ||
279 | return 0; | 282 | return 0; |
280 | 283 | ||
281 | spd->pages = kmalloc(pipe->buffers * sizeof(struct page *), GFP_KERNEL); | 284 | spd->pages = kmalloc(buffers * sizeof(struct page *), GFP_KERNEL); |
282 | spd->partial = kmalloc(pipe->buffers * sizeof(struct partial_page), GFP_KERNEL); | 285 | spd->partial = kmalloc(buffers * sizeof(struct partial_page), GFP_KERNEL); |
283 | 286 | ||
284 | if (spd->pages && spd->partial) | 287 | if (spd->pages && spd->partial) |
285 | return 0; | 288 | return 0; |
@@ -289,10 +292,9 @@ int splice_grow_spd(struct pipe_inode_info *pipe, struct splice_pipe_desc *spd) | |||
289 | return -ENOMEM; | 292 | return -ENOMEM; |
290 | } | 293 | } |
291 | 294 | ||
292 | void splice_shrink_spd(struct pipe_inode_info *pipe, | 295 | void splice_shrink_spd(struct splice_pipe_desc *spd) |
293 | struct splice_pipe_desc *spd) | ||
294 | { | 296 | { |
295 | if (pipe->buffers <= PIPE_DEF_BUFFERS) | 297 | if (spd->nr_pages_max <= PIPE_DEF_BUFFERS) |
296 | return; | 298 | return; |
297 | 299 | ||
298 | kfree(spd->pages); | 300 | kfree(spd->pages); |
@@ -315,6 +317,7 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, | |||
315 | struct splice_pipe_desc spd = { | 317 | struct splice_pipe_desc spd = { |
316 | .pages = pages, | 318 | .pages = pages, |
317 | .partial = partial, | 319 | .partial = partial, |
320 | .nr_pages_max = PIPE_DEF_BUFFERS, | ||
318 | .flags = flags, | 321 | .flags = flags, |
319 | .ops = &page_cache_pipe_buf_ops, | 322 | .ops = &page_cache_pipe_buf_ops, |
320 | .spd_release = spd_release_page, | 323 | .spd_release = spd_release_page, |
@@ -326,7 +329,7 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, | |||
326 | index = *ppos >> PAGE_CACHE_SHIFT; | 329 | index = *ppos >> PAGE_CACHE_SHIFT; |
327 | loff = *ppos & ~PAGE_CACHE_MASK; | 330 | loff = *ppos & ~PAGE_CACHE_MASK; |
328 | req_pages = (len + loff + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | 331 | req_pages = (len + loff + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; |
329 | nr_pages = min(req_pages, pipe->buffers); | 332 | nr_pages = min(req_pages, spd.nr_pages_max); |
330 | 333 | ||
331 | /* | 334 | /* |
332 | * Lookup the (hopefully) full range of pages we need. | 335 | * Lookup the (hopefully) full range of pages we need. |
@@ -497,7 +500,7 @@ fill_it: | |||
497 | if (spd.nr_pages) | 500 | if (spd.nr_pages) |
498 | error = splice_to_pipe(pipe, &spd); | 501 | error = splice_to_pipe(pipe, &spd); |
499 | 502 | ||
500 | splice_shrink_spd(pipe, &spd); | 503 | splice_shrink_spd(&spd); |
501 | return error; | 504 | return error; |
502 | } | 505 | } |
503 | 506 | ||
@@ -598,6 +601,7 @@ ssize_t default_file_splice_read(struct file *in, loff_t *ppos, | |||
598 | struct splice_pipe_desc spd = { | 601 | struct splice_pipe_desc spd = { |
599 | .pages = pages, | 602 | .pages = pages, |
600 | .partial = partial, | 603 | .partial = partial, |
604 | .nr_pages_max = PIPE_DEF_BUFFERS, | ||
601 | .flags = flags, | 605 | .flags = flags, |
602 | .ops = &default_pipe_buf_ops, | 606 | .ops = &default_pipe_buf_ops, |
603 | .spd_release = spd_release_page, | 607 | .spd_release = spd_release_page, |
@@ -608,8 +612,8 @@ ssize_t default_file_splice_read(struct file *in, loff_t *ppos, | |||
608 | 612 | ||
609 | res = -ENOMEM; | 613 | res = -ENOMEM; |
610 | vec = __vec; | 614 | vec = __vec; |
611 | if (pipe->buffers > PIPE_DEF_BUFFERS) { | 615 | if (spd.nr_pages_max > PIPE_DEF_BUFFERS) { |
612 | vec = kmalloc(pipe->buffers * sizeof(struct iovec), GFP_KERNEL); | 616 | vec = kmalloc(spd.nr_pages_max * sizeof(struct iovec), GFP_KERNEL); |
613 | if (!vec) | 617 | if (!vec) |
614 | goto shrink_ret; | 618 | goto shrink_ret; |
615 | } | 619 | } |
@@ -617,7 +621,7 @@ ssize_t default_file_splice_read(struct file *in, loff_t *ppos, | |||
617 | offset = *ppos & ~PAGE_CACHE_MASK; | 621 | offset = *ppos & ~PAGE_CACHE_MASK; |
618 | nr_pages = (len + offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | 622 | nr_pages = (len + offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; |
619 | 623 | ||
620 | for (i = 0; i < nr_pages && i < pipe->buffers && len; i++) { | 624 | for (i = 0; i < nr_pages && i < spd.nr_pages_max && len; i++) { |
621 | struct page *page; | 625 | struct page *page; |
622 | 626 | ||
623 | page = alloc_page(GFP_USER); | 627 | page = alloc_page(GFP_USER); |
@@ -665,7 +669,7 @@ ssize_t default_file_splice_read(struct file *in, loff_t *ppos, | |||
665 | shrink_ret: | 669 | shrink_ret: |
666 | if (vec != __vec) | 670 | if (vec != __vec) |
667 | kfree(vec); | 671 | kfree(vec); |
668 | splice_shrink_spd(pipe, &spd); | 672 | splice_shrink_spd(&spd); |
669 | return res; | 673 | return res; |
670 | 674 | ||
671 | err: | 675 | err: |
@@ -1614,6 +1618,7 @@ static long vmsplice_to_pipe(struct file *file, const struct iovec __user *iov, | |||
1614 | struct splice_pipe_desc spd = { | 1618 | struct splice_pipe_desc spd = { |
1615 | .pages = pages, | 1619 | .pages = pages, |
1616 | .partial = partial, | 1620 | .partial = partial, |
1621 | .nr_pages_max = PIPE_DEF_BUFFERS, | ||
1617 | .flags = flags, | 1622 | .flags = flags, |
1618 | .ops = &user_page_pipe_buf_ops, | 1623 | .ops = &user_page_pipe_buf_ops, |
1619 | .spd_release = spd_release_page, | 1624 | .spd_release = spd_release_page, |
@@ -1629,13 +1634,13 @@ static long vmsplice_to_pipe(struct file *file, const struct iovec __user *iov, | |||
1629 | 1634 | ||
1630 | spd.nr_pages = get_iovec_page_array(iov, nr_segs, spd.pages, | 1635 | spd.nr_pages = get_iovec_page_array(iov, nr_segs, spd.pages, |
1631 | spd.partial, false, | 1636 | spd.partial, false, |
1632 | pipe->buffers); | 1637 | spd.nr_pages_max); |
1633 | if (spd.nr_pages <= 0) | 1638 | if (spd.nr_pages <= 0) |
1634 | ret = spd.nr_pages; | 1639 | ret = spd.nr_pages; |
1635 | else | 1640 | else |
1636 | ret = splice_to_pipe(pipe, &spd); | 1641 | ret = splice_to_pipe(pipe, &spd); |
1637 | 1642 | ||
1638 | splice_shrink_spd(pipe, &spd); | 1643 | splice_shrink_spd(&spd); |
1639 | return ret; | 1644 | return ret; |
1640 | } | 1645 | } |
1641 | 1646 | ||
diff --git a/fs/squashfs/namei.c b/fs/squashfs/namei.c index abcc58f3c152..7834a517f7f4 100644 --- a/fs/squashfs/namei.c +++ b/fs/squashfs/namei.c | |||
@@ -134,7 +134,7 @@ out: | |||
134 | 134 | ||
135 | 135 | ||
136 | static struct dentry *squashfs_lookup(struct inode *dir, struct dentry *dentry, | 136 | static struct dentry *squashfs_lookup(struct inode *dir, struct dentry *dentry, |
137 | struct nameidata *nd) | 137 | unsigned int flags) |
138 | { | 138 | { |
139 | const unsigned char *name = dentry->d_name.name; | 139 | const unsigned char *name = dentry->d_name.name; |
140 | int len = dentry->d_name.len; | 140 | int len = dentry->d_name.len; |
diff --git a/fs/super.c b/fs/super.c index cf001775617f..c743fb3be4b8 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -105,11 +105,12 @@ static int prune_super(struct shrinker *shrink, struct shrink_control *sc) | |||
105 | /** | 105 | /** |
106 | * alloc_super - create new superblock | 106 | * alloc_super - create new superblock |
107 | * @type: filesystem type superblock should belong to | 107 | * @type: filesystem type superblock should belong to |
108 | * @flags: the mount flags | ||
108 | * | 109 | * |
109 | * Allocates and initializes a new &struct super_block. alloc_super() | 110 | * Allocates and initializes a new &struct super_block. alloc_super() |
110 | * returns a pointer new superblock or %NULL if allocation had failed. | 111 | * returns a pointer new superblock or %NULL if allocation had failed. |
111 | */ | 112 | */ |
112 | static struct super_block *alloc_super(struct file_system_type *type) | 113 | static struct super_block *alloc_super(struct file_system_type *type, int flags) |
113 | { | 114 | { |
114 | struct super_block *s = kzalloc(sizeof(struct super_block), GFP_USER); | 115 | struct super_block *s = kzalloc(sizeof(struct super_block), GFP_USER); |
115 | static const struct super_operations default_op; | 116 | static const struct super_operations default_op; |
@@ -136,6 +137,7 @@ static struct super_block *alloc_super(struct file_system_type *type) | |||
136 | #else | 137 | #else |
137 | INIT_LIST_HEAD(&s->s_files); | 138 | INIT_LIST_HEAD(&s->s_files); |
138 | #endif | 139 | #endif |
140 | s->s_flags = flags; | ||
139 | s->s_bdi = &default_backing_dev_info; | 141 | s->s_bdi = &default_backing_dev_info; |
140 | INIT_HLIST_NODE(&s->s_instances); | 142 | INIT_HLIST_NODE(&s->s_instances); |
141 | INIT_HLIST_BL_HEAD(&s->s_anon); | 143 | INIT_HLIST_BL_HEAD(&s->s_anon); |
@@ -415,11 +417,13 @@ EXPORT_SYMBOL(generic_shutdown_super); | |||
415 | * @type: filesystem type superblock should belong to | 417 | * @type: filesystem type superblock should belong to |
416 | * @test: comparison callback | 418 | * @test: comparison callback |
417 | * @set: setup callback | 419 | * @set: setup callback |
420 | * @flags: mount flags | ||
418 | * @data: argument to each of them | 421 | * @data: argument to each of them |
419 | */ | 422 | */ |
420 | struct super_block *sget(struct file_system_type *type, | 423 | struct super_block *sget(struct file_system_type *type, |
421 | int (*test)(struct super_block *,void *), | 424 | int (*test)(struct super_block *,void *), |
422 | int (*set)(struct super_block *,void *), | 425 | int (*set)(struct super_block *,void *), |
426 | int flags, | ||
423 | void *data) | 427 | void *data) |
424 | { | 428 | { |
425 | struct super_block *s = NULL; | 429 | struct super_block *s = NULL; |
@@ -450,7 +454,7 @@ retry: | |||
450 | } | 454 | } |
451 | if (!s) { | 455 | if (!s) { |
452 | spin_unlock(&sb_lock); | 456 | spin_unlock(&sb_lock); |
453 | s = alloc_super(type); | 457 | s = alloc_super(type, flags); |
454 | if (!s) | 458 | if (!s) |
455 | return ERR_PTR(-ENOMEM); | 459 | return ERR_PTR(-ENOMEM); |
456 | goto retry; | 460 | goto retry; |
@@ -925,13 +929,12 @@ struct dentry *mount_ns(struct file_system_type *fs_type, int flags, | |||
925 | { | 929 | { |
926 | struct super_block *sb; | 930 | struct super_block *sb; |
927 | 931 | ||
928 | sb = sget(fs_type, ns_test_super, ns_set_super, data); | 932 | sb = sget(fs_type, ns_test_super, ns_set_super, flags, data); |
929 | if (IS_ERR(sb)) | 933 | if (IS_ERR(sb)) |
930 | return ERR_CAST(sb); | 934 | return ERR_CAST(sb); |
931 | 935 | ||
932 | if (!sb->s_root) { | 936 | if (!sb->s_root) { |
933 | int err; | 937 | int err; |
934 | sb->s_flags = flags; | ||
935 | err = fill_super(sb, data, flags & MS_SILENT ? 1 : 0); | 938 | err = fill_super(sb, data, flags & MS_SILENT ? 1 : 0); |
936 | if (err) { | 939 | if (err) { |
937 | deactivate_locked_super(sb); | 940 | deactivate_locked_super(sb); |
@@ -992,7 +995,8 @@ struct dentry *mount_bdev(struct file_system_type *fs_type, | |||
992 | error = -EBUSY; | 995 | error = -EBUSY; |
993 | goto error_bdev; | 996 | goto error_bdev; |
994 | } | 997 | } |
995 | s = sget(fs_type, test_bdev_super, set_bdev_super, bdev); | 998 | s = sget(fs_type, test_bdev_super, set_bdev_super, flags | MS_NOSEC, |
999 | bdev); | ||
996 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | 1000 | mutex_unlock(&bdev->bd_fsfreeze_mutex); |
997 | if (IS_ERR(s)) | 1001 | if (IS_ERR(s)) |
998 | goto error_s; | 1002 | goto error_s; |
@@ -1017,7 +1021,6 @@ struct dentry *mount_bdev(struct file_system_type *fs_type, | |||
1017 | } else { | 1021 | } else { |
1018 | char b[BDEVNAME_SIZE]; | 1022 | char b[BDEVNAME_SIZE]; |
1019 | 1023 | ||
1020 | s->s_flags = flags | MS_NOSEC; | ||
1021 | s->s_mode = mode; | 1024 | s->s_mode = mode; |
1022 | strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); | 1025 | strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); |
1023 | sb_set_blocksize(s, block_size(bdev)); | 1026 | sb_set_blocksize(s, block_size(bdev)); |
@@ -1062,13 +1065,11 @@ struct dentry *mount_nodev(struct file_system_type *fs_type, | |||
1062 | int (*fill_super)(struct super_block *, void *, int)) | 1065 | int (*fill_super)(struct super_block *, void *, int)) |
1063 | { | 1066 | { |
1064 | int error; | 1067 | int error; |
1065 | struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL); | 1068 | struct super_block *s = sget(fs_type, NULL, set_anon_super, flags, NULL); |
1066 | 1069 | ||
1067 | if (IS_ERR(s)) | 1070 | if (IS_ERR(s)) |
1068 | return ERR_CAST(s); | 1071 | return ERR_CAST(s); |
1069 | 1072 | ||
1070 | s->s_flags = flags; | ||
1071 | |||
1072 | error = fill_super(s, data, flags & MS_SILENT ? 1 : 0); | 1073 | error = fill_super(s, data, flags & MS_SILENT ? 1 : 0); |
1073 | if (error) { | 1074 | if (error) { |
1074 | deactivate_locked_super(s); | 1075 | deactivate_locked_super(s); |
@@ -1091,11 +1092,10 @@ struct dentry *mount_single(struct file_system_type *fs_type, | |||
1091 | struct super_block *s; | 1092 | struct super_block *s; |
1092 | int error; | 1093 | int error; |
1093 | 1094 | ||
1094 | s = sget(fs_type, compare_single, set_anon_super, NULL); | 1095 | s = sget(fs_type, compare_single, set_anon_super, flags, NULL); |
1095 | if (IS_ERR(s)) | 1096 | if (IS_ERR(s)) |
1096 | return ERR_CAST(s); | 1097 | return ERR_CAST(s); |
1097 | if (!s->s_root) { | 1098 | if (!s->s_root) { |
1098 | s->s_flags = flags; | ||
1099 | error = fill_super(s, data, flags & MS_SILENT ? 1 : 0); | 1099 | error = fill_super(s, data, flags & MS_SILENT ? 1 : 0); |
1100 | if (error) { | 1100 | if (error) { |
1101 | deactivate_locked_super(s); | 1101 | deactivate_locked_super(s); |
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index e6bb9b2a4cbe..a5cf784f9cc2 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
@@ -300,15 +300,15 @@ void release_sysfs_dirent(struct sysfs_dirent * sd) | |||
300 | static int sysfs_dentry_delete(const struct dentry *dentry) | 300 | static int sysfs_dentry_delete(const struct dentry *dentry) |
301 | { | 301 | { |
302 | struct sysfs_dirent *sd = dentry->d_fsdata; | 302 | struct sysfs_dirent *sd = dentry->d_fsdata; |
303 | return !!(sd->s_flags & SYSFS_FLAG_REMOVED); | 303 | return !(sd && !(sd->s_flags & SYSFS_FLAG_REMOVED)); |
304 | } | 304 | } |
305 | 305 | ||
306 | static int sysfs_dentry_revalidate(struct dentry *dentry, struct nameidata *nd) | 306 | static int sysfs_dentry_revalidate(struct dentry *dentry, unsigned int flags) |
307 | { | 307 | { |
308 | struct sysfs_dirent *sd; | 308 | struct sysfs_dirent *sd; |
309 | int is_dir; | 309 | int is_dir; |
310 | 310 | ||
311 | if (nd->flags & LOOKUP_RCU) | 311 | if (flags & LOOKUP_RCU) |
312 | return -ECHILD; | 312 | return -ECHILD; |
313 | 313 | ||
314 | sd = dentry->d_fsdata; | 314 | sd = dentry->d_fsdata; |
@@ -355,18 +355,15 @@ out_bad: | |||
355 | return 0; | 355 | return 0; |
356 | } | 356 | } |
357 | 357 | ||
358 | static void sysfs_dentry_iput(struct dentry *dentry, struct inode *inode) | 358 | static void sysfs_dentry_release(struct dentry *dentry) |
359 | { | 359 | { |
360 | struct sysfs_dirent * sd = dentry->d_fsdata; | 360 | sysfs_put(dentry->d_fsdata); |
361 | |||
362 | sysfs_put(sd); | ||
363 | iput(inode); | ||
364 | } | 361 | } |
365 | 362 | ||
366 | static const struct dentry_operations sysfs_dentry_ops = { | 363 | const struct dentry_operations sysfs_dentry_ops = { |
367 | .d_revalidate = sysfs_dentry_revalidate, | 364 | .d_revalidate = sysfs_dentry_revalidate, |
368 | .d_delete = sysfs_dentry_delete, | 365 | .d_delete = sysfs_dentry_delete, |
369 | .d_iput = sysfs_dentry_iput, | 366 | .d_release = sysfs_dentry_release, |
370 | }; | 367 | }; |
371 | 368 | ||
372 | struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type) | 369 | struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type) |
@@ -764,7 +761,7 @@ int sysfs_create_dir(struct kobject * kobj) | |||
764 | } | 761 | } |
765 | 762 | ||
766 | static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, | 763 | static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, |
767 | struct nameidata *nd) | 764 | unsigned int flags) |
768 | { | 765 | { |
769 | struct dentry *ret = NULL; | 766 | struct dentry *ret = NULL; |
770 | struct dentry *parent = dentry->d_parent; | 767 | struct dentry *parent = dentry->d_parent; |
@@ -786,6 +783,7 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, | |||
786 | ret = ERR_PTR(-ENOENT); | 783 | ret = ERR_PTR(-ENOENT); |
787 | goto out_unlock; | 784 | goto out_unlock; |
788 | } | 785 | } |
786 | dentry->d_fsdata = sysfs_get(sd); | ||
789 | 787 | ||
790 | /* attach dentry and inode */ | 788 | /* attach dentry and inode */ |
791 | inode = sysfs_get_inode(dir->i_sb, sd); | 789 | inode = sysfs_get_inode(dir->i_sb, sd); |
@@ -795,16 +793,7 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, | |||
795 | } | 793 | } |
796 | 794 | ||
797 | /* instantiate and hash dentry */ | 795 | /* instantiate and hash dentry */ |
798 | ret = d_find_alias(inode); | 796 | ret = d_materialise_unique(dentry, inode); |
799 | if (!ret) { | ||
800 | d_set_d_op(dentry, &sysfs_dentry_ops); | ||
801 | dentry->d_fsdata = sysfs_get(sd); | ||
802 | d_add(dentry, inode); | ||
803 | } else { | ||
804 | d_move(ret, dentry); | ||
805 | iput(inode); | ||
806 | } | ||
807 | |||
808 | out_unlock: | 797 | out_unlock: |
809 | mutex_unlock(&sysfs_mutex); | 798 | mutex_unlock(&sysfs_mutex); |
810 | return ret; | 799 | return ret; |
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c index 52c3bdb66a84..71eb7e253927 100644 --- a/fs/sysfs/mount.c +++ b/fs/sysfs/mount.c | |||
@@ -68,6 +68,7 @@ static int sysfs_fill_super(struct super_block *sb, void *data, int silent) | |||
68 | } | 68 | } |
69 | root->d_fsdata = &sysfs_root; | 69 | root->d_fsdata = &sysfs_root; |
70 | sb->s_root = root; | 70 | sb->s_root = root; |
71 | sb->s_d_op = &sysfs_dentry_ops; | ||
71 | return 0; | 72 | return 0; |
72 | } | 73 | } |
73 | 74 | ||
@@ -117,13 +118,12 @@ static struct dentry *sysfs_mount(struct file_system_type *fs_type, | |||
117 | for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++) | 118 | for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++) |
118 | info->ns[type] = kobj_ns_grab_current(type); | 119 | info->ns[type] = kobj_ns_grab_current(type); |
119 | 120 | ||
120 | sb = sget(fs_type, sysfs_test_super, sysfs_set_super, info); | 121 | sb = sget(fs_type, sysfs_test_super, sysfs_set_super, flags, info); |
121 | if (IS_ERR(sb) || sb->s_fs_info != info) | 122 | if (IS_ERR(sb) || sb->s_fs_info != info) |
122 | free_sysfs_super_info(info); | 123 | free_sysfs_super_info(info); |
123 | if (IS_ERR(sb)) | 124 | if (IS_ERR(sb)) |
124 | return ERR_CAST(sb); | 125 | return ERR_CAST(sb); |
125 | if (!sb->s_root) { | 126 | if (!sb->s_root) { |
126 | sb->s_flags = flags; | ||
127 | error = sysfs_fill_super(sb, data, flags & MS_SILENT ? 1 : 0); | 127 | error = sysfs_fill_super(sb, data, flags & MS_SILENT ? 1 : 0); |
128 | if (error) { | 128 | if (error) { |
129 | deactivate_locked_super(sb); | 129 | deactivate_locked_super(sb); |
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index 661a9639570b..d73c0932bbd6 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h | |||
@@ -157,6 +157,7 @@ extern struct kmem_cache *sysfs_dir_cachep; | |||
157 | */ | 157 | */ |
158 | extern struct mutex sysfs_mutex; | 158 | extern struct mutex sysfs_mutex; |
159 | extern spinlock_t sysfs_assoc_lock; | 159 | extern spinlock_t sysfs_assoc_lock; |
160 | extern const struct dentry_operations sysfs_dentry_ops; | ||
160 | 161 | ||
161 | extern const struct file_operations sysfs_dir_operations; | 162 | extern const struct file_operations sysfs_dir_operations; |
162 | extern const struct inode_operations sysfs_dir_inode_operations; | 163 | extern const struct inode_operations sysfs_dir_inode_operations; |
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c index d7466e293614..1c0d5f264767 100644 --- a/fs/sysv/namei.c +++ b/fs/sysv/namei.c | |||
@@ -43,7 +43,7 @@ const struct dentry_operations sysv_dentry_operations = { | |||
43 | .d_hash = sysv_hash, | 43 | .d_hash = sysv_hash, |
44 | }; | 44 | }; |
45 | 45 | ||
46 | static struct dentry *sysv_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd) | 46 | static struct dentry *sysv_lookup(struct inode * dir, struct dentry * dentry, unsigned int flags) |
47 | { | 47 | { |
48 | struct inode * inode = NULL; | 48 | struct inode * inode = NULL; |
49 | ino_t ino; | 49 | ino_t ino; |
@@ -80,7 +80,7 @@ static int sysv_mknod(struct inode * dir, struct dentry * dentry, umode_t mode, | |||
80 | return err; | 80 | return err; |
81 | } | 81 | } |
82 | 82 | ||
83 | static int sysv_create(struct inode * dir, struct dentry * dentry, umode_t mode, struct nameidata *nd) | 83 | static int sysv_create(struct inode * dir, struct dentry * dentry, umode_t mode, bool excl) |
84 | { | 84 | { |
85 | return sysv_mknod(dir, dentry, mode, 0); | 85 | return sysv_mknod(dir, dentry, mode, 0); |
86 | } | 86 | } |
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c index 84a7e6f3c046..92df3b081539 100644 --- a/fs/ubifs/debug.c +++ b/fs/ubifs/debug.c | |||
@@ -2918,7 +2918,7 @@ int dbg_debugfs_init_fs(struct ubifs_info *c) | |||
2918 | struct dentry *dent; | 2918 | struct dentry *dent; |
2919 | struct ubifs_debug_info *d = c->dbg; | 2919 | struct ubifs_debug_info *d = c->dbg; |
2920 | 2920 | ||
2921 | if (!IS_ENABLED(DEBUG_FS)) | 2921 | if (!IS_ENABLED(CONFIG_DEBUG_FS)) |
2922 | return 0; | 2922 | return 0; |
2923 | 2923 | ||
2924 | n = snprintf(d->dfs_dir_name, UBIFS_DFS_DIR_LEN + 1, UBIFS_DFS_DIR_NAME, | 2924 | n = snprintf(d->dfs_dir_name, UBIFS_DFS_DIR_LEN + 1, UBIFS_DFS_DIR_NAME, |
@@ -3013,7 +3013,7 @@ out: | |||
3013 | */ | 3013 | */ |
3014 | void dbg_debugfs_exit_fs(struct ubifs_info *c) | 3014 | void dbg_debugfs_exit_fs(struct ubifs_info *c) |
3015 | { | 3015 | { |
3016 | if (IS_ENABLED(DEBUG_FS)) | 3016 | if (IS_ENABLED(CONFIG_DEBUG_FS)) |
3017 | debugfs_remove_recursive(c->dbg->dfs_dir); | 3017 | debugfs_remove_recursive(c->dbg->dfs_dir); |
3018 | } | 3018 | } |
3019 | 3019 | ||
@@ -3099,7 +3099,7 @@ int dbg_debugfs_init(void) | |||
3099 | const char *fname; | 3099 | const char *fname; |
3100 | struct dentry *dent; | 3100 | struct dentry *dent; |
3101 | 3101 | ||
3102 | if (!IS_ENABLED(DEBUG_FS)) | 3102 | if (!IS_ENABLED(CONFIG_DEBUG_FS)) |
3103 | return 0; | 3103 | return 0; |
3104 | 3104 | ||
3105 | fname = "ubifs"; | 3105 | fname = "ubifs"; |
@@ -3166,7 +3166,7 @@ out: | |||
3166 | */ | 3166 | */ |
3167 | void dbg_debugfs_exit(void) | 3167 | void dbg_debugfs_exit(void) |
3168 | { | 3168 | { |
3169 | if (IS_ENABLED(DEBUG_FS)) | 3169 | if (IS_ENABLED(CONFIG_DEBUG_FS)) |
3170 | debugfs_remove_recursive(dfs_rootdir); | 3170 | debugfs_remove_recursive(dfs_rootdir); |
3171 | } | 3171 | } |
3172 | 3172 | ||
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index a6d42efc76d2..b1cca89aeb68 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c | |||
@@ -184,7 +184,7 @@ static int dbg_check_name(const struct ubifs_info *c, | |||
184 | } | 184 | } |
185 | 185 | ||
186 | static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry, | 186 | static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry, |
187 | struct nameidata *nd) | 187 | unsigned int flags) |
188 | { | 188 | { |
189 | int err; | 189 | int err; |
190 | union ubifs_key key; | 190 | union ubifs_key key; |
@@ -246,7 +246,7 @@ out: | |||
246 | } | 246 | } |
247 | 247 | ||
248 | static int ubifs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 248 | static int ubifs_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
249 | struct nameidata *nd) | 249 | bool excl) |
250 | { | 250 | { |
251 | struct inode *inode; | 251 | struct inode *inode; |
252 | struct ubifs_info *c = dir->i_sb->s_fs_info; | 252 | struct ubifs_info *c = dir->i_sb->s_fs_info; |
diff --git a/fs/ubifs/find.c b/fs/ubifs/find.c index 2559d174e004..28ec13af28d9 100644 --- a/fs/ubifs/find.c +++ b/fs/ubifs/find.c | |||
@@ -939,8 +939,8 @@ static int find_dirtiest_idx_leb(struct ubifs_info *c) | |||
939 | } | 939 | } |
940 | dbg_find("LEB %d, dirty %d and free %d flags %#x", lp->lnum, lp->dirty, | 940 | dbg_find("LEB %d, dirty %d and free %d flags %#x", lp->lnum, lp->dirty, |
941 | lp->free, lp->flags); | 941 | lp->free, lp->flags); |
942 | ubifs_assert(lp->flags | LPROPS_TAKEN); | 942 | ubifs_assert(lp->flags & LPROPS_TAKEN); |
943 | ubifs_assert(lp->flags | LPROPS_INDEX); | 943 | ubifs_assert(lp->flags & LPROPS_INDEX); |
944 | return lnum; | 944 | return lnum; |
945 | } | 945 | } |
946 | 946 | ||
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 5862dd9d2784..1c766c39c038 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -2136,7 +2136,7 @@ static struct dentry *ubifs_mount(struct file_system_type *fs_type, int flags, | |||
2136 | 2136 | ||
2137 | dbg_gen("opened ubi%d_%d", c->vi.ubi_num, c->vi.vol_id); | 2137 | dbg_gen("opened ubi%d_%d", c->vi.ubi_num, c->vi.vol_id); |
2138 | 2138 | ||
2139 | sb = sget(fs_type, sb_test, sb_set, c); | 2139 | sb = sget(fs_type, sb_test, sb_set, flags, c); |
2140 | if (IS_ERR(sb)) { | 2140 | if (IS_ERR(sb)) { |
2141 | err = PTR_ERR(sb); | 2141 | err = PTR_ERR(sb); |
2142 | kfree(c); | 2142 | kfree(c); |
@@ -2153,7 +2153,6 @@ static struct dentry *ubifs_mount(struct file_system_type *fs_type, int flags, | |||
2153 | goto out_deact; | 2153 | goto out_deact; |
2154 | } | 2154 | } |
2155 | } else { | 2155 | } else { |
2156 | sb->s_flags = flags; | ||
2157 | err = ubifs_fill_super(sb, data, flags & MS_SILENT ? 1 : 0); | 2156 | err = ubifs_fill_super(sb, data, flags & MS_SILENT ? 1 : 0); |
2158 | if (err) | 2157 | if (err) |
2159 | goto out_deact; | 2158 | goto out_deact; |
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 18024178ac4c..544b2799a911 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -251,7 +251,7 @@ out_ok: | |||
251 | } | 251 | } |
252 | 252 | ||
253 | static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry, | 253 | static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry, |
254 | struct nameidata *nd) | 254 | unsigned int flags) |
255 | { | 255 | { |
256 | struct inode *inode = NULL; | 256 | struct inode *inode = NULL; |
257 | struct fileIdentDesc cfi; | 257 | struct fileIdentDesc cfi; |
@@ -551,7 +551,7 @@ static int udf_delete_entry(struct inode *inode, struct fileIdentDesc *fi, | |||
551 | } | 551 | } |
552 | 552 | ||
553 | static int udf_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 553 | static int udf_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
554 | struct nameidata *nd) | 554 | bool excl) |
555 | { | 555 | { |
556 | struct udf_fileident_bh fibh; | 556 | struct udf_fileident_bh fibh; |
557 | struct inode *inode; | 557 | struct inode *inode; |
diff --git a/fs/udf/super.c b/fs/udf/super.c index ac8a348dcb69..8d86a8706c0e 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -56,6 +56,7 @@ | |||
56 | #include <linux/seq_file.h> | 56 | #include <linux/seq_file.h> |
57 | #include <linux/bitmap.h> | 57 | #include <linux/bitmap.h> |
58 | #include <linux/crc-itu-t.h> | 58 | #include <linux/crc-itu-t.h> |
59 | #include <linux/log2.h> | ||
59 | #include <asm/byteorder.h> | 60 | #include <asm/byteorder.h> |
60 | 61 | ||
61 | #include "udf_sb.h" | 62 | #include "udf_sb.h" |
@@ -1215,16 +1216,65 @@ out_bh: | |||
1215 | return ret; | 1216 | return ret; |
1216 | } | 1217 | } |
1217 | 1218 | ||
1219 | static int udf_load_sparable_map(struct super_block *sb, | ||
1220 | struct udf_part_map *map, | ||
1221 | struct sparablePartitionMap *spm) | ||
1222 | { | ||
1223 | uint32_t loc; | ||
1224 | uint16_t ident; | ||
1225 | struct sparingTable *st; | ||
1226 | struct udf_sparing_data *sdata = &map->s_type_specific.s_sparing; | ||
1227 | int i; | ||
1228 | struct buffer_head *bh; | ||
1229 | |||
1230 | map->s_partition_type = UDF_SPARABLE_MAP15; | ||
1231 | sdata->s_packet_len = le16_to_cpu(spm->packetLength); | ||
1232 | if (!is_power_of_2(sdata->s_packet_len)) { | ||
1233 | udf_err(sb, "error loading logical volume descriptor: " | ||
1234 | "Invalid packet length %u\n", | ||
1235 | (unsigned)sdata->s_packet_len); | ||
1236 | return -EIO; | ||
1237 | } | ||
1238 | if (spm->numSparingTables > 4) { | ||
1239 | udf_err(sb, "error loading logical volume descriptor: " | ||
1240 | "Too many sparing tables (%d)\n", | ||
1241 | (int)spm->numSparingTables); | ||
1242 | return -EIO; | ||
1243 | } | ||
1244 | |||
1245 | for (i = 0; i < spm->numSparingTables; i++) { | ||
1246 | loc = le32_to_cpu(spm->locSparingTable[i]); | ||
1247 | bh = udf_read_tagged(sb, loc, loc, &ident); | ||
1248 | if (!bh) | ||
1249 | continue; | ||
1250 | |||
1251 | st = (struct sparingTable *)bh->b_data; | ||
1252 | if (ident != 0 || | ||
1253 | strncmp(st->sparingIdent.ident, UDF_ID_SPARING, | ||
1254 | strlen(UDF_ID_SPARING)) || | ||
1255 | sizeof(*st) + le16_to_cpu(st->reallocationTableLen) > | ||
1256 | sb->s_blocksize) { | ||
1257 | brelse(bh); | ||
1258 | continue; | ||
1259 | } | ||
1260 | |||
1261 | sdata->s_spar_map[i] = bh; | ||
1262 | } | ||
1263 | map->s_partition_func = udf_get_pblock_spar15; | ||
1264 | return 0; | ||
1265 | } | ||
1266 | |||
1218 | static int udf_load_logicalvol(struct super_block *sb, sector_t block, | 1267 | static int udf_load_logicalvol(struct super_block *sb, sector_t block, |
1219 | struct kernel_lb_addr *fileset) | 1268 | struct kernel_lb_addr *fileset) |
1220 | { | 1269 | { |
1221 | struct logicalVolDesc *lvd; | 1270 | struct logicalVolDesc *lvd; |
1222 | int i, j, offset; | 1271 | int i, offset; |
1223 | uint8_t type; | 1272 | uint8_t type; |
1224 | struct udf_sb_info *sbi = UDF_SB(sb); | 1273 | struct udf_sb_info *sbi = UDF_SB(sb); |
1225 | struct genericPartitionMap *gpm; | 1274 | struct genericPartitionMap *gpm; |
1226 | uint16_t ident; | 1275 | uint16_t ident; |
1227 | struct buffer_head *bh; | 1276 | struct buffer_head *bh; |
1277 | unsigned int table_len; | ||
1228 | int ret = 0; | 1278 | int ret = 0; |
1229 | 1279 | ||
1230 | bh = udf_read_tagged(sb, block, block, &ident); | 1280 | bh = udf_read_tagged(sb, block, block, &ident); |
@@ -1232,15 +1282,20 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block, | |||
1232 | return 1; | 1282 | return 1; |
1233 | BUG_ON(ident != TAG_IDENT_LVD); | 1283 | BUG_ON(ident != TAG_IDENT_LVD); |
1234 | lvd = (struct logicalVolDesc *)bh->b_data; | 1284 | lvd = (struct logicalVolDesc *)bh->b_data; |
1235 | 1285 | table_len = le32_to_cpu(lvd->mapTableLength); | |
1236 | i = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps)); | 1286 | if (sizeof(*lvd) + table_len > sb->s_blocksize) { |
1237 | if (i != 0) { | 1287 | udf_err(sb, "error loading logical volume descriptor: " |
1238 | ret = i; | 1288 | "Partition table too long (%u > %lu)\n", table_len, |
1289 | sb->s_blocksize - sizeof(*lvd)); | ||
1239 | goto out_bh; | 1290 | goto out_bh; |
1240 | } | 1291 | } |
1241 | 1292 | ||
1293 | ret = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps)); | ||
1294 | if (ret) | ||
1295 | goto out_bh; | ||
1296 | |||
1242 | for (i = 0, offset = 0; | 1297 | for (i = 0, offset = 0; |
1243 | i < sbi->s_partitions && offset < le32_to_cpu(lvd->mapTableLength); | 1298 | i < sbi->s_partitions && offset < table_len; |
1244 | i++, offset += gpm->partitionMapLength) { | 1299 | i++, offset += gpm->partitionMapLength) { |
1245 | struct udf_part_map *map = &sbi->s_partmaps[i]; | 1300 | struct udf_part_map *map = &sbi->s_partmaps[i]; |
1246 | gpm = (struct genericPartitionMap *) | 1301 | gpm = (struct genericPartitionMap *) |
@@ -1275,38 +1330,9 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block, | |||
1275 | } else if (!strncmp(upm2->partIdent.ident, | 1330 | } else if (!strncmp(upm2->partIdent.ident, |
1276 | UDF_ID_SPARABLE, | 1331 | UDF_ID_SPARABLE, |
1277 | strlen(UDF_ID_SPARABLE))) { | 1332 | strlen(UDF_ID_SPARABLE))) { |
1278 | uint32_t loc; | 1333 | if (udf_load_sparable_map(sb, map, |
1279 | struct sparingTable *st; | 1334 | (struct sparablePartitionMap *)gpm) < 0) |
1280 | struct sparablePartitionMap *spm = | 1335 | goto out_bh; |
1281 | (struct sparablePartitionMap *)gpm; | ||
1282 | |||
1283 | map->s_partition_type = UDF_SPARABLE_MAP15; | ||
1284 | map->s_type_specific.s_sparing.s_packet_len = | ||
1285 | le16_to_cpu(spm->packetLength); | ||
1286 | for (j = 0; j < spm->numSparingTables; j++) { | ||
1287 | struct buffer_head *bh2; | ||
1288 | |||
1289 | loc = le32_to_cpu( | ||
1290 | spm->locSparingTable[j]); | ||
1291 | bh2 = udf_read_tagged(sb, loc, loc, | ||
1292 | &ident); | ||
1293 | map->s_type_specific.s_sparing. | ||
1294 | s_spar_map[j] = bh2; | ||
1295 | |||
1296 | if (bh2 == NULL) | ||
1297 | continue; | ||
1298 | |||
1299 | st = (struct sparingTable *)bh2->b_data; | ||
1300 | if (ident != 0 || strncmp( | ||
1301 | st->sparingIdent.ident, | ||
1302 | UDF_ID_SPARING, | ||
1303 | strlen(UDF_ID_SPARING))) { | ||
1304 | brelse(bh2); | ||
1305 | map->s_type_specific.s_sparing. | ||
1306 | s_spar_map[j] = NULL; | ||
1307 | } | ||
1308 | } | ||
1309 | map->s_partition_func = udf_get_pblock_spar15; | ||
1310 | } else if (!strncmp(upm2->partIdent.ident, | 1336 | } else if (!strncmp(upm2->partIdent.ident, |
1311 | UDF_ID_METADATA, | 1337 | UDF_ID_METADATA, |
1312 | strlen(UDF_ID_METADATA))) { | 1338 | strlen(UDF_ID_METADATA))) { |
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index a2281cadefa1..90d74b8f8eba 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c | |||
@@ -46,7 +46,7 @@ static inline int ufs_add_nondir(struct dentry *dentry, struct inode *inode) | |||
46 | return err; | 46 | return err; |
47 | } | 47 | } |
48 | 48 | ||
49 | static struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd) | 49 | static struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry, unsigned int flags) |
50 | { | 50 | { |
51 | struct inode * inode = NULL; | 51 | struct inode * inode = NULL; |
52 | ino_t ino; | 52 | ino_t ino; |
@@ -71,7 +71,7 @@ static struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry, stru | |||
71 | * with d_instantiate(). | 71 | * with d_instantiate(). |
72 | */ | 72 | */ |
73 | static int ufs_create (struct inode * dir, struct dentry * dentry, umode_t mode, | 73 | static int ufs_create (struct inode * dir, struct dentry * dentry, umode_t mode, |
74 | struct nameidata *nd) | 74 | bool excl) |
75 | { | 75 | { |
76 | struct inode *inode; | 76 | struct inode *inode; |
77 | int err; | 77 | int err; |
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 1a25fd802798..9c4340f5c3e0 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c | |||
@@ -179,7 +179,7 @@ xfs_vn_create( | |||
179 | struct inode *dir, | 179 | struct inode *dir, |
180 | struct dentry *dentry, | 180 | struct dentry *dentry, |
181 | umode_t mode, | 181 | umode_t mode, |
182 | struct nameidata *nd) | 182 | bool flags) |
183 | { | 183 | { |
184 | return xfs_vn_mknod(dir, dentry, mode, 0); | 184 | return xfs_vn_mknod(dir, dentry, mode, 0); |
185 | } | 185 | } |
@@ -197,7 +197,7 @@ STATIC struct dentry * | |||
197 | xfs_vn_lookup( | 197 | xfs_vn_lookup( |
198 | struct inode *dir, | 198 | struct inode *dir, |
199 | struct dentry *dentry, | 199 | struct dentry *dentry, |
200 | struct nameidata *nd) | 200 | unsigned int flags) |
201 | { | 201 | { |
202 | struct xfs_inode *cip; | 202 | struct xfs_inode *cip; |
203 | struct xfs_name name; | 203 | struct xfs_name name; |
@@ -222,7 +222,7 @@ STATIC struct dentry * | |||
222 | xfs_vn_ci_lookup( | 222 | xfs_vn_ci_lookup( |
223 | struct inode *dir, | 223 | struct inode *dir, |
224 | struct dentry *dentry, | 224 | struct dentry *dentry, |
225 | struct nameidata *nd) | 225 | unsigned int flags) |
226 | { | 226 | { |
227 | struct xfs_inode *ip; | 227 | struct xfs_inode *ip; |
228 | struct xfs_name xname; | 228 | struct xfs_name xname; |