diff options
Diffstat (limited to 'fs')
152 files changed, 1528 insertions, 1452 deletions
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h index bab0eac873f4..b789f8e597ec 100644 --- a/fs/9p/v9fs_vfs.h +++ b/fs/9p/v9fs_vfs.h | |||
@@ -59,7 +59,6 @@ void v9fs_stat2inode_dotl(struct p9_stat_dotl *, struct inode *); | |||
59 | int v9fs_dir_release(struct inode *inode, struct file *filp); | 59 | int v9fs_dir_release(struct inode *inode, struct file *filp); |
60 | int v9fs_file_open(struct inode *inode, struct file *file); | 60 | int v9fs_file_open(struct inode *inode, struct file *file); |
61 | void v9fs_inode2stat(struct inode *inode, struct p9_wstat *stat); | 61 | void v9fs_inode2stat(struct inode *inode, struct p9_wstat *stat); |
62 | void v9fs_dentry_release(struct dentry *); | ||
63 | int v9fs_uflags2omode(int uflags, int extended); | 62 | int v9fs_uflags2omode(int uflags, int extended); |
64 | 63 | ||
65 | ssize_t v9fs_file_readn(struct file *, char *, char __user *, u32, u64); | 64 | ssize_t v9fs_file_readn(struct file *, char *, char __user *, u32, u64); |
diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c index 466d2a4fc5cb..233b7d4ffe5e 100644 --- a/fs/9p/vfs_dentry.c +++ b/fs/9p/vfs_dentry.c | |||
@@ -86,7 +86,7 @@ static int v9fs_cached_dentry_delete(const struct dentry *dentry) | |||
86 | * | 86 | * |
87 | */ | 87 | */ |
88 | 88 | ||
89 | void v9fs_dentry_release(struct dentry *dentry) | 89 | static void v9fs_dentry_release(struct dentry *dentry) |
90 | { | 90 | { |
91 | struct v9fs_dentry *dent; | 91 | struct v9fs_dentry *dent; |
92 | struct p9_fid *temp, *current_fid; | 92 | struct p9_fid *temp, *current_fid; |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 5076eeb95502..b76a40bdf4c2 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -699,11 +699,6 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, | |||
699 | goto error_iput; | 699 | goto error_iput; |
700 | 700 | ||
701 | inst_out: | 701 | inst_out: |
702 | if (v9ses->cache) | ||
703 | d_set_d_op(dentry, &v9fs_cached_dentry_operations); | ||
704 | else | ||
705 | d_set_d_op(dentry, &v9fs_dentry_operations); | ||
706 | |||
707 | d_add(dentry, inode); | 702 | d_add(dentry, inode); |
708 | return NULL; | 703 | return NULL; |
709 | 704 | ||
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index c55c614500ad..dbaabe3b8131 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c | |||
@@ -141,6 +141,11 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags, | |||
141 | } | 141 | } |
142 | v9fs_fill_super(sb, v9ses, flags, data); | 142 | v9fs_fill_super(sb, v9ses, flags, data); |
143 | 143 | ||
144 | if (v9ses->cache) | ||
145 | sb->s_d_op = &v9fs_cached_dentry_operations; | ||
146 | else | ||
147 | sb->s_d_op = &v9fs_dentry_operations; | ||
148 | |||
144 | inode = v9fs_get_inode(sb, S_IFDIR | mode); | 149 | inode = v9fs_get_inode(sb, S_IFDIR | mode); |
145 | if (IS_ERR(inode)) { | 150 | if (IS_ERR(inode)) { |
146 | retval = PTR_ERR(inode); | 151 | retval = PTR_ERR(inode); |
@@ -217,9 +222,6 @@ static void v9fs_kill_super(struct super_block *s) | |||
217 | 222 | ||
218 | P9_DPRINTK(P9_DEBUG_VFS, " %p\n", s); | 223 | P9_DPRINTK(P9_DEBUG_VFS, " %p\n", s); |
219 | 224 | ||
220 | if (s->s_root) | ||
221 | v9fs_dentry_release(s->s_root); /* clunk root */ | ||
222 | |||
223 | kill_anon_super(s); | 225 | kill_anon_super(s); |
224 | 226 | ||
225 | v9fs_session_cancel(v9ses); | 227 | v9fs_session_cancel(v9ses); |
diff --git a/fs/adfs/dir.c b/fs/adfs/dir.c index bf7693c384f9..3b4a764ed780 100644 --- a/fs/adfs/dir.c +++ b/fs/adfs/dir.c | |||
@@ -276,7 +276,6 @@ adfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | |||
276 | struct object_info obj; | 276 | struct object_info obj; |
277 | int error; | 277 | int error; |
278 | 278 | ||
279 | d_set_d_op(dentry, &adfs_dentry_operations); | ||
280 | lock_kernel(); | 279 | lock_kernel(); |
281 | error = adfs_dir_lookup_byname(dir, &dentry->d_name, &obj); | 280 | error = adfs_dir_lookup_byname(dir, &dentry->d_name, &obj); |
282 | if (error == 0) { | 281 | if (error == 0) { |
diff --git a/fs/adfs/super.c b/fs/adfs/super.c index a4041b52fbca..2d7954049fbe 100644 --- a/fs/adfs/super.c +++ b/fs/adfs/super.c | |||
@@ -473,6 +473,7 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent) | |||
473 | asb->s_namelen = ADFS_F_NAME_LEN; | 473 | asb->s_namelen = ADFS_F_NAME_LEN; |
474 | } | 474 | } |
475 | 475 | ||
476 | sb->s_d_op = &adfs_dentry_operations; | ||
476 | root = adfs_iget(sb, &root_obj); | 477 | root = adfs_iget(sb, &root_obj); |
477 | sb->s_root = d_alloc_root(root); | 478 | sb->s_root = d_alloc_root(root); |
478 | if (!sb->s_root) { | 479 | if (!sb->s_root) { |
@@ -483,8 +484,7 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent) | |||
483 | kfree(asb->s_map); | 484 | kfree(asb->s_map); |
484 | adfs_error(sb, "get root inode failed\n"); | 485 | adfs_error(sb, "get root inode failed\n"); |
485 | goto error; | 486 | goto error; |
486 | } else | 487 | } |
487 | d_set_d_op(sb->s_root, &adfs_dentry_operations); | ||
488 | unlock_kernel(); | 488 | unlock_kernel(); |
489 | return 0; | 489 | return 0; |
490 | 490 | ||
diff --git a/fs/affs/affs.h b/fs/affs/affs.h index a8cbdeb34025..0e95f73a7023 100644 --- a/fs/affs/affs.h +++ b/fs/affs/affs.h | |||
@@ -201,6 +201,7 @@ extern const struct address_space_operations affs_aops; | |||
201 | extern const struct address_space_operations affs_aops_ofs; | 201 | extern const struct address_space_operations affs_aops_ofs; |
202 | 202 | ||
203 | extern const struct dentry_operations affs_dentry_operations; | 203 | extern const struct dentry_operations affs_dentry_operations; |
204 | extern const struct dentry_operations affs_intl_dentry_operations; | ||
204 | 205 | ||
205 | static inline void | 206 | static inline void |
206 | affs_set_blocksize(struct super_block *sb, int size) | 207 | affs_set_blocksize(struct super_block *sb, int size) |
diff --git a/fs/affs/namei.c b/fs/affs/namei.c index 944a4042fb65..e3e9efc1fdd8 100644 --- a/fs/affs/namei.c +++ b/fs/affs/namei.c | |||
@@ -32,7 +32,7 @@ const struct dentry_operations affs_dentry_operations = { | |||
32 | .d_compare = affs_compare_dentry, | 32 | .d_compare = affs_compare_dentry, |
33 | }; | 33 | }; |
34 | 34 | ||
35 | static const struct dentry_operations affs_intl_dentry_operations = { | 35 | const struct dentry_operations affs_intl_dentry_operations = { |
36 | .d_hash = affs_intl_hash_dentry, | 36 | .d_hash = affs_intl_hash_dentry, |
37 | .d_compare = affs_intl_compare_dentry, | 37 | .d_compare = affs_intl_compare_dentry, |
38 | }; | 38 | }; |
@@ -240,7 +240,6 @@ affs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | |||
240 | if (IS_ERR(inode)) | 240 | if (IS_ERR(inode)) |
241 | return ERR_CAST(inode); | 241 | return ERR_CAST(inode); |
242 | } | 242 | } |
243 | d_set_d_op(dentry, AFFS_SB(sb)->s_flags & SF_INTL ? &affs_intl_dentry_operations : &affs_dentry_operations); | ||
244 | d_add(dentry, inode); | 243 | d_add(dentry, inode); |
245 | return NULL; | 244 | return NULL; |
246 | } | 245 | } |
diff --git a/fs/affs/super.c b/fs/affs/super.c index d39081bbe7ce..b31507d0f9b9 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c | |||
@@ -477,12 +477,16 @@ got_root: | |||
477 | goto out_error_noinode; | 477 | goto out_error_noinode; |
478 | } | 478 | } |
479 | 479 | ||
480 | if (AFFS_SB(sb)->s_flags & SF_INTL) | ||
481 | sb->s_d_op = &affs_intl_dentry_operations; | ||
482 | else | ||
483 | sb->s_d_op = &affs_dentry_operations; | ||
484 | |||
480 | sb->s_root = d_alloc_root(root_inode); | 485 | sb->s_root = d_alloc_root(root_inode); |
481 | if (!sb->s_root) { | 486 | if (!sb->s_root) { |
482 | printk(KERN_ERR "AFFS: Get root inode failed\n"); | 487 | printk(KERN_ERR "AFFS: Get root inode failed\n"); |
483 | goto out_error; | 488 | goto out_error; |
484 | } | 489 | } |
485 | d_set_d_op(sb->s_root, &affs_dentry_operations); | ||
486 | 490 | ||
487 | pr_debug("AFFS: s_flags=%lX\n",sb->s_flags); | 491 | pr_debug("AFFS: s_flags=%lX\n",sb->s_flags); |
488 | return 0; | 492 | return 0; |
diff --git a/fs/afs/dir.c b/fs/afs/dir.c index 34a3263d60a4..e6a4ab980e31 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c | |||
@@ -62,7 +62,7 @@ const struct inode_operations afs_dir_inode_operations = { | |||
62 | .setattr = afs_setattr, | 62 | .setattr = afs_setattr, |
63 | }; | 63 | }; |
64 | 64 | ||
65 | static const struct dentry_operations afs_fs_dentry_operations = { | 65 | const struct dentry_operations afs_fs_dentry_operations = { |
66 | .d_revalidate = afs_d_revalidate, | 66 | .d_revalidate = afs_d_revalidate, |
67 | .d_delete = afs_d_delete, | 67 | .d_delete = afs_d_delete, |
68 | .d_release = afs_d_release, | 68 | .d_release = afs_d_release, |
@@ -582,8 +582,6 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, | |||
582 | } | 582 | } |
583 | 583 | ||
584 | success: | 584 | success: |
585 | d_set_d_op(dentry, &afs_fs_dentry_operations); | ||
586 | |||
587 | d_add(dentry, inode); | 585 | d_add(dentry, inode); |
588 | _leave(" = 0 { vn=%u u=%u } -> { ino=%lu v=%llu }", | 586 | _leave(" = 0 { vn=%u u=%u } -> { ino=%lu v=%llu }", |
589 | fid.vnode, | 587 | fid.vnode, |
diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 6d4bc1c8ff60..ab6db5abaf53 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h | |||
@@ -486,6 +486,7 @@ extern bool afs_cm_incoming_call(struct afs_call *); | |||
486 | * dir.c | 486 | * dir.c |
487 | */ | 487 | */ |
488 | extern const struct inode_operations afs_dir_inode_operations; | 488 | extern const struct inode_operations afs_dir_inode_operations; |
489 | extern const struct dentry_operations afs_fs_dentry_operations; | ||
489 | extern const struct file_operations afs_dir_file_operations; | 490 | extern const struct file_operations afs_dir_file_operations; |
490 | 491 | ||
491 | /* | 492 | /* |
diff --git a/fs/afs/super.c b/fs/afs/super.c index f901a9d7c111..fb240e8766d6 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c | |||
@@ -336,6 +336,7 @@ static int afs_fill_super(struct super_block *sb, void *data) | |||
336 | if (!root) | 336 | if (!root) |
337 | goto error; | 337 | goto error; |
338 | 338 | ||
339 | sb->s_d_op = &afs_fs_dentry_operations; | ||
339 | sb->s_root = root; | 340 | sb->s_root = root; |
340 | 341 | ||
341 | _leave(" = 0"); | 342 | _leave(" = 0"); |
@@ -798,29 +798,12 @@ static void aio_queue_work(struct kioctx * ctx) | |||
798 | queue_delayed_work(aio_wq, &ctx->wq, timeout); | 798 | queue_delayed_work(aio_wq, &ctx->wq, timeout); |
799 | } | 799 | } |
800 | 800 | ||
801 | |||
802 | /* | ||
803 | * aio_run_iocbs: | ||
804 | * Process all pending retries queued on the ioctx | ||
805 | * run list. | ||
806 | * Assumes it is operating within the aio issuer's mm | ||
807 | * context. | ||
808 | */ | ||
809 | static inline void aio_run_iocbs(struct kioctx *ctx) | ||
810 | { | ||
811 | int requeue; | ||
812 | |||
813 | spin_lock_irq(&ctx->ctx_lock); | ||
814 | |||
815 | requeue = __aio_run_iocbs(ctx); | ||
816 | spin_unlock_irq(&ctx->ctx_lock); | ||
817 | if (requeue) | ||
818 | aio_queue_work(ctx); | ||
819 | } | ||
820 | |||
821 | /* | 801 | /* |
822 | * just like aio_run_iocbs, but keeps running them until | 802 | * aio_run_all_iocbs: |
823 | * the list stays empty | 803 | * Process all pending retries queued on the ioctx |
804 | * run list, and keep running them until the list | ||
805 | * stays empty. | ||
806 | * Assumes it is operating within the aio issuer's mm context. | ||
824 | */ | 807 | */ |
825 | static inline void aio_run_all_iocbs(struct kioctx *ctx) | 808 | static inline void aio_run_all_iocbs(struct kioctx *ctx) |
826 | { | 809 | { |
@@ -1839,7 +1822,7 @@ SYSCALL_DEFINE5(io_getevents, aio_context_t, ctx_id, | |||
1839 | long ret = -EINVAL; | 1822 | long ret = -EINVAL; |
1840 | 1823 | ||
1841 | if (likely(ioctx)) { | 1824 | if (likely(ioctx)) { |
1842 | if (likely(min_nr <= nr && min_nr >= 0 && nr >= 0)) | 1825 | if (likely(min_nr <= nr && min_nr >= 0)) |
1843 | ret = read_events(ioctx, min_nr, nr, events, timeout); | 1826 | ret = read_events(ioctx, min_nr, nr, events, timeout); |
1844 | put_ioctx(ioctx); | 1827 | put_ioctx(ioctx); |
1845 | } | 1828 | } |
diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c index 5fd38112a6ca..cbe57f3c4d89 100644 --- a/fs/anon_inodes.c +++ b/fs/anon_inodes.c | |||
@@ -26,12 +26,6 @@ static struct vfsmount *anon_inode_mnt __read_mostly; | |||
26 | static struct inode *anon_inode_inode; | 26 | static struct inode *anon_inode_inode; |
27 | static const struct file_operations anon_inode_fops; | 27 | static const struct file_operations anon_inode_fops; |
28 | 28 | ||
29 | static struct dentry *anon_inodefs_mount(struct file_system_type *fs_type, | ||
30 | int flags, const char *dev_name, void *data) | ||
31 | { | ||
32 | return mount_pseudo(fs_type, "anon_inode:", NULL, ANON_INODE_FS_MAGIC); | ||
33 | } | ||
34 | |||
35 | /* | 29 | /* |
36 | * anon_inodefs_dname() is called from d_path(). | 30 | * anon_inodefs_dname() is called from d_path(). |
37 | */ | 31 | */ |
@@ -41,14 +35,22 @@ static char *anon_inodefs_dname(struct dentry *dentry, char *buffer, int buflen) | |||
41 | dentry->d_name.name); | 35 | dentry->d_name.name); |
42 | } | 36 | } |
43 | 37 | ||
38 | static const struct dentry_operations anon_inodefs_dentry_operations = { | ||
39 | .d_dname = anon_inodefs_dname, | ||
40 | }; | ||
41 | |||
42 | static struct dentry *anon_inodefs_mount(struct file_system_type *fs_type, | ||
43 | int flags, const char *dev_name, void *data) | ||
44 | { | ||
45 | return mount_pseudo(fs_type, "anon_inode:", NULL, | ||
46 | &anon_inodefs_dentry_operations, ANON_INODE_FS_MAGIC); | ||
47 | } | ||
48 | |||
44 | static struct file_system_type anon_inode_fs_type = { | 49 | static struct file_system_type anon_inode_fs_type = { |
45 | .name = "anon_inodefs", | 50 | .name = "anon_inodefs", |
46 | .mount = anon_inodefs_mount, | 51 | .mount = anon_inodefs_mount, |
47 | .kill_sb = kill_anon_super, | 52 | .kill_sb = kill_anon_super, |
48 | }; | 53 | }; |
49 | static const struct dentry_operations anon_inodefs_dentry_operations = { | ||
50 | .d_dname = anon_inodefs_dname, | ||
51 | }; | ||
52 | 54 | ||
53 | /* | 55 | /* |
54 | * nop .set_page_dirty method so that people can use .page_mkwrite on | 56 | * nop .set_page_dirty method so that people can use .page_mkwrite on |
@@ -64,9 +66,9 @@ static const struct address_space_operations anon_aops = { | |||
64 | }; | 66 | }; |
65 | 67 | ||
66 | /** | 68 | /** |
67 | * anon_inode_getfd - creates a new file instance by hooking it up to an | 69 | * anon_inode_getfile - creates a new file instance by hooking it up to an |
68 | * anonymous inode, and a dentry that describe the "class" | 70 | * anonymous inode, and a dentry that describe the "class" |
69 | * of the file | 71 | * of the file |
70 | * | 72 | * |
71 | * @name: [in] name of the "class" of the new file | 73 | * @name: [in] name of the "class" of the new file |
72 | * @fops: [in] file operations for the new file | 74 | * @fops: [in] file operations for the new file |
@@ -113,7 +115,6 @@ struct file *anon_inode_getfile(const char *name, | |||
113 | */ | 115 | */ |
114 | ihold(anon_inode_inode); | 116 | ihold(anon_inode_inode); |
115 | 117 | ||
116 | d_set_d_op(path.dentry, &anon_inodefs_dentry_operations); | ||
117 | d_instantiate(path.dentry, anon_inode_inode); | 118 | d_instantiate(path.dentry, anon_inode_inode); |
118 | 119 | ||
119 | error = -ENFILE; | 120 | error = -ENFILE; |
diff --git a/fs/befs/endian.h b/fs/befs/endian.h index 6cb84d896d05..27223878ba9f 100644 --- a/fs/befs/endian.h +++ b/fs/befs/endian.h | |||
@@ -102,22 +102,22 @@ cpu_to_fsrun(const struct super_block *sb, befs_block_run n) | |||
102 | } | 102 | } |
103 | 103 | ||
104 | static inline befs_data_stream | 104 | static inline befs_data_stream |
105 | fsds_to_cpu(const struct super_block *sb, befs_disk_data_stream n) | 105 | fsds_to_cpu(const struct super_block *sb, const befs_disk_data_stream *n) |
106 | { | 106 | { |
107 | befs_data_stream data; | 107 | befs_data_stream data; |
108 | int i; | 108 | int i; |
109 | 109 | ||
110 | for (i = 0; i < BEFS_NUM_DIRECT_BLOCKS; ++i) | 110 | for (i = 0; i < BEFS_NUM_DIRECT_BLOCKS; ++i) |
111 | data.direct[i] = fsrun_to_cpu(sb, n.direct[i]); | 111 | data.direct[i] = fsrun_to_cpu(sb, n->direct[i]); |
112 | 112 | ||
113 | data.max_direct_range = fs64_to_cpu(sb, n.max_direct_range); | 113 | data.max_direct_range = fs64_to_cpu(sb, n->max_direct_range); |
114 | data.indirect = fsrun_to_cpu(sb, n.indirect); | 114 | data.indirect = fsrun_to_cpu(sb, n->indirect); |
115 | data.max_indirect_range = fs64_to_cpu(sb, n.max_indirect_range); | 115 | data.max_indirect_range = fs64_to_cpu(sb, n->max_indirect_range); |
116 | data.double_indirect = fsrun_to_cpu(sb, n.double_indirect); | 116 | data.double_indirect = fsrun_to_cpu(sb, n->double_indirect); |
117 | data.max_double_indirect_range = fs64_to_cpu(sb, | 117 | data.max_double_indirect_range = fs64_to_cpu(sb, |
118 | n. | 118 | n-> |
119 | max_double_indirect_range); | 119 | max_double_indirect_range); |
120 | data.size = fs64_to_cpu(sb, n.size); | 120 | data.size = fs64_to_cpu(sb, n->size); |
121 | 121 | ||
122 | return data; | 122 | return data; |
123 | } | 123 | } |
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index de93581b79a2..b1d0c794747b 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c | |||
@@ -390,7 +390,7 @@ static struct inode *befs_iget(struct super_block *sb, unsigned long ino) | |||
390 | int num_blks; | 390 | int num_blks; |
391 | 391 | ||
392 | befs_ino->i_data.ds = | 392 | befs_ino->i_data.ds = |
393 | fsds_to_cpu(sb, raw_inode->data.datastream); | 393 | fsds_to_cpu(sb, &raw_inode->data.datastream); |
394 | 394 | ||
395 | num_blks = befs_count_blocks(sb, &befs_ino->i_data.ds); | 395 | num_blks = befs_count_blocks(sb, &befs_ino->i_data.ds); |
396 | inode->i_blocks = | 396 | inode->i_blocks = |
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 6884e198e0c7..d5b640ba6cb1 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -66,12 +66,11 @@ static int elf_core_dump(struct coredump_params *cprm); | |||
66 | #define ELF_PAGEALIGN(_v) (((_v) + ELF_MIN_ALIGN - 1) & ~(ELF_MIN_ALIGN - 1)) | 66 | #define ELF_PAGEALIGN(_v) (((_v) + ELF_MIN_ALIGN - 1) & ~(ELF_MIN_ALIGN - 1)) |
67 | 67 | ||
68 | static struct linux_binfmt elf_format = { | 68 | static struct linux_binfmt elf_format = { |
69 | .module = THIS_MODULE, | 69 | .module = THIS_MODULE, |
70 | .load_binary = load_elf_binary, | 70 | .load_binary = load_elf_binary, |
71 | .load_shlib = load_elf_library, | 71 | .load_shlib = load_elf_library, |
72 | .core_dump = elf_core_dump, | 72 | .core_dump = elf_core_dump, |
73 | .min_coredump = ELF_EXEC_PAGESIZE, | 73 | .min_coredump = ELF_EXEC_PAGESIZE, |
74 | .hasvdso = 1 | ||
75 | }; | 74 | }; |
76 | 75 | ||
77 | #define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE) | 76 | #define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE) |
@@ -316,8 +315,6 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, | |||
316 | return 0; | 315 | return 0; |
317 | } | 316 | } |
318 | 317 | ||
319 | #ifndef elf_map | ||
320 | |||
321 | static unsigned long elf_map(struct file *filep, unsigned long addr, | 318 | static unsigned long elf_map(struct file *filep, unsigned long addr, |
322 | struct elf_phdr *eppnt, int prot, int type, | 319 | struct elf_phdr *eppnt, int prot, int type, |
323 | unsigned long total_size) | 320 | unsigned long total_size) |
@@ -354,8 +351,6 @@ static unsigned long elf_map(struct file *filep, unsigned long addr, | |||
354 | return(map_addr); | 351 | return(map_addr); |
355 | } | 352 | } |
356 | 353 | ||
357 | #endif /* !elf_map */ | ||
358 | |||
359 | static unsigned long total_mapping_size(struct elf_phdr *cmds, int nr) | 354 | static unsigned long total_mapping_size(struct elf_phdr *cmds, int nr) |
360 | { | 355 | { |
361 | int i, first_idx = -1, last_idx = -1; | 356 | int i, first_idx = -1, last_idx = -1; |
@@ -421,7 +416,7 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, | |||
421 | goto out; | 416 | goto out; |
422 | 417 | ||
423 | retval = kernel_read(interpreter, interp_elf_ex->e_phoff, | 418 | retval = kernel_read(interpreter, interp_elf_ex->e_phoff, |
424 | (char *)elf_phdata,size); | 419 | (char *)elf_phdata, size); |
425 | error = -EIO; | 420 | error = -EIO; |
426 | if (retval != size) { | 421 | if (retval != size) { |
427 | if (retval < 0) | 422 | if (retval < 0) |
@@ -601,7 +596,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
601 | goto out; | 596 | goto out; |
602 | if (!elf_check_arch(&loc->elf_ex)) | 597 | if (!elf_check_arch(&loc->elf_ex)) |
603 | goto out; | 598 | goto out; |
604 | if (!bprm->file->f_op||!bprm->file->f_op->mmap) | 599 | if (!bprm->file->f_op || !bprm->file->f_op->mmap) |
605 | goto out; | 600 | goto out; |
606 | 601 | ||
607 | /* Now read in all of the header information */ | 602 | /* Now read in all of the header information */ |
@@ -761,8 +756,8 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
761 | /* There was a PT_LOAD segment with p_memsz > p_filesz | 756 | /* There was a PT_LOAD segment with p_memsz > p_filesz |
762 | before this one. Map anonymous pages, if needed, | 757 | before this one. Map anonymous pages, if needed, |
763 | and clear the area. */ | 758 | and clear the area. */ |
764 | retval = set_brk (elf_bss + load_bias, | 759 | retval = set_brk(elf_bss + load_bias, |
765 | elf_brk + load_bias); | 760 | elf_brk + load_bias); |
766 | if (retval) { | 761 | if (retval) { |
767 | send_sig(SIGKILL, current, 0); | 762 | send_sig(SIGKILL, current, 0); |
768 | goto out_free_dentry; | 763 | goto out_free_dentry; |
diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c index 4d0ff5ee27b8..e49cce234c65 100644 --- a/fs/bio-integrity.c +++ b/fs/bio-integrity.c | |||
@@ -782,7 +782,12 @@ void __init bio_integrity_init(void) | |||
782 | { | 782 | { |
783 | unsigned int i; | 783 | unsigned int i; |
784 | 784 | ||
785 | kintegrityd_wq = create_workqueue("kintegrityd"); | 785 | /* |
786 | * kintegrityd won't block much but may burn a lot of CPU cycles. | ||
787 | * Make it highpri CPU intensive wq with max concurrency of 1. | ||
788 | */ | ||
789 | kintegrityd_wq = alloc_workqueue("kintegrityd", WQ_MEM_RECLAIM | | ||
790 | WQ_HIGHPRI | WQ_CPU_INTENSIVE, 1); | ||
786 | if (!kintegrityd_wq) | 791 | if (!kintegrityd_wq) |
787 | panic("Failed to create kintegrityd\n"); | 792 | panic("Failed to create kintegrityd\n"); |
788 | 793 | ||
diff --git a/fs/block_dev.c b/fs/block_dev.c index 771f23527010..fe3f59c14a02 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -432,9 +432,6 @@ static void init_once(void *foo) | |||
432 | mutex_init(&bdev->bd_mutex); | 432 | mutex_init(&bdev->bd_mutex); |
433 | INIT_LIST_HEAD(&bdev->bd_inodes); | 433 | INIT_LIST_HEAD(&bdev->bd_inodes); |
434 | INIT_LIST_HEAD(&bdev->bd_list); | 434 | INIT_LIST_HEAD(&bdev->bd_list); |
435 | #ifdef CONFIG_SYSFS | ||
436 | INIT_LIST_HEAD(&bdev->bd_holder_list); | ||
437 | #endif | ||
438 | inode_init_once(&ei->vfs_inode); | 435 | inode_init_once(&ei->vfs_inode); |
439 | /* Initialize mutex for freeze. */ | 436 | /* Initialize mutex for freeze. */ |
440 | mutex_init(&bdev->bd_fsfreeze_mutex); | 437 | mutex_init(&bdev->bd_fsfreeze_mutex); |
@@ -473,7 +470,7 @@ static const struct super_operations bdev_sops = { | |||
473 | static struct dentry *bd_mount(struct file_system_type *fs_type, | 470 | static struct dentry *bd_mount(struct file_system_type *fs_type, |
474 | int flags, const char *dev_name, void *data) | 471 | int flags, const char *dev_name, void *data) |
475 | { | 472 | { |
476 | return mount_pseudo(fs_type, "bdev:", &bdev_sops, 0x62646576); | 473 | return mount_pseudo(fs_type, "bdev:", &bdev_sops, NULL, 0x62646576); |
477 | } | 474 | } |
478 | 475 | ||
479 | static struct file_system_type bd_type = { | 476 | static struct file_system_type bd_type = { |
@@ -669,7 +666,7 @@ static bool bd_may_claim(struct block_device *bdev, struct block_device *whole, | |||
669 | else if (bdev->bd_contains == bdev) | 666 | else if (bdev->bd_contains == bdev) |
670 | return true; /* is a whole device which isn't held */ | 667 | return true; /* is a whole device which isn't held */ |
671 | 668 | ||
672 | else if (whole->bd_holder == bd_claim) | 669 | else if (whole->bd_holder == bd_may_claim) |
673 | return true; /* is a partition of a device that is being partitioned */ | 670 | return true; /* is a partition of a device that is being partitioned */ |
674 | else if (whole->bd_holder != NULL) | 671 | else if (whole->bd_holder != NULL) |
675 | return false; /* is a partition of a held device */ | 672 | return false; /* is a partition of a held device */ |
@@ -781,439 +778,87 @@ static struct block_device *bd_start_claiming(struct block_device *bdev, | |||
781 | } | 778 | } |
782 | } | 779 | } |
783 | 780 | ||
784 | /* releases bdev_lock */ | ||
785 | static void __bd_abort_claiming(struct block_device *whole, void *holder) | ||
786 | { | ||
787 | BUG_ON(whole->bd_claiming != holder); | ||
788 | whole->bd_claiming = NULL; | ||
789 | wake_up_bit(&whole->bd_claiming, 0); | ||
790 | |||
791 | spin_unlock(&bdev_lock); | ||
792 | bdput(whole); | ||
793 | } | ||
794 | |||
795 | /** | ||
796 | * bd_abort_claiming - abort claiming a block device | ||
797 | * @whole: whole block device returned by bd_start_claiming() | ||
798 | * @holder: holder trying to claim @bdev | ||
799 | * | ||
800 | * Abort a claiming block started by bd_start_claiming(). Note that | ||
801 | * @whole is not the block device to be claimed but the whole device | ||
802 | * returned by bd_start_claiming(). | ||
803 | * | ||
804 | * CONTEXT: | ||
805 | * Grabs and releases bdev_lock. | ||
806 | */ | ||
807 | static void bd_abort_claiming(struct block_device *whole, void *holder) | ||
808 | { | ||
809 | spin_lock(&bdev_lock); | ||
810 | __bd_abort_claiming(whole, holder); /* releases bdev_lock */ | ||
811 | } | ||
812 | |||
813 | /* increment holders when we have a legitimate claim. requires bdev_lock */ | ||
814 | static void __bd_claim(struct block_device *bdev, struct block_device *whole, | ||
815 | void *holder) | ||
816 | { | ||
817 | /* note that for a whole device bd_holders | ||
818 | * will be incremented twice, and bd_holder will | ||
819 | * be set to bd_claim before being set to holder | ||
820 | */ | ||
821 | whole->bd_holders++; | ||
822 | whole->bd_holder = bd_claim; | ||
823 | bdev->bd_holders++; | ||
824 | bdev->bd_holder = holder; | ||
825 | } | ||
826 | |||
827 | /** | ||
828 | * bd_finish_claiming - finish claiming a block device | ||
829 | * @bdev: block device of interest (passed to bd_start_claiming()) | ||
830 | * @whole: whole block device returned by bd_start_claiming() | ||
831 | * @holder: holder trying to claim @bdev | ||
832 | * | ||
833 | * Finish a claiming block started by bd_start_claiming(). | ||
834 | * | ||
835 | * CONTEXT: | ||
836 | * Grabs and releases bdev_lock. | ||
837 | */ | ||
838 | static void bd_finish_claiming(struct block_device *bdev, | ||
839 | struct block_device *whole, void *holder) | ||
840 | { | ||
841 | spin_lock(&bdev_lock); | ||
842 | BUG_ON(!bd_may_claim(bdev, whole, holder)); | ||
843 | __bd_claim(bdev, whole, holder); | ||
844 | __bd_abort_claiming(whole, holder); /* not actually an abort */ | ||
845 | } | ||
846 | |||
847 | /** | ||
848 | * bd_claim - claim a block device | ||
849 | * @bdev: block device to claim | ||
850 | * @holder: holder trying to claim @bdev | ||
851 | * | ||
852 | * Try to claim @bdev which must have been opened successfully. | ||
853 | * | ||
854 | * CONTEXT: | ||
855 | * Might sleep. | ||
856 | * | ||
857 | * RETURNS: | ||
858 | * 0 if successful, -EBUSY if @bdev is already claimed. | ||
859 | */ | ||
860 | int bd_claim(struct block_device *bdev, void *holder) | ||
861 | { | ||
862 | struct block_device *whole = bdev->bd_contains; | ||
863 | int res; | ||
864 | |||
865 | might_sleep(); | ||
866 | |||
867 | spin_lock(&bdev_lock); | ||
868 | res = bd_prepare_to_claim(bdev, whole, holder); | ||
869 | if (res == 0) | ||
870 | __bd_claim(bdev, whole, holder); | ||
871 | spin_unlock(&bdev_lock); | ||
872 | |||
873 | return res; | ||
874 | } | ||
875 | EXPORT_SYMBOL(bd_claim); | ||
876 | |||
877 | void bd_release(struct block_device *bdev) | ||
878 | { | ||
879 | spin_lock(&bdev_lock); | ||
880 | if (!--bdev->bd_contains->bd_holders) | ||
881 | bdev->bd_contains->bd_holder = NULL; | ||
882 | if (!--bdev->bd_holders) | ||
883 | bdev->bd_holder = NULL; | ||
884 | spin_unlock(&bdev_lock); | ||
885 | } | ||
886 | |||
887 | EXPORT_SYMBOL(bd_release); | ||
888 | |||
889 | #ifdef CONFIG_SYSFS | 781 | #ifdef CONFIG_SYSFS |
890 | /* | ||
891 | * Functions for bd_claim_by_kobject / bd_release_from_kobject | ||
892 | * | ||
893 | * If a kobject is passed to bd_claim_by_kobject() | ||
894 | * and the kobject has a parent directory, | ||
895 | * following symlinks are created: | ||
896 | * o from the kobject to the claimed bdev | ||
897 | * o from "holders" directory of the bdev to the parent of the kobject | ||
898 | * bd_release_from_kobject() removes these symlinks. | ||
899 | * | ||
900 | * Example: | ||
901 | * If /dev/dm-0 maps to /dev/sda, kobject corresponding to | ||
902 | * /sys/block/dm-0/slaves is passed to bd_claim_by_kobject(), then: | ||
903 | * /sys/block/dm-0/slaves/sda --> /sys/block/sda | ||
904 | * /sys/block/sda/holders/dm-0 --> /sys/block/dm-0 | ||
905 | */ | ||
906 | |||
907 | static int add_symlink(struct kobject *from, struct kobject *to) | 782 | static int add_symlink(struct kobject *from, struct kobject *to) |
908 | { | 783 | { |
909 | if (!from || !to) | ||
910 | return 0; | ||
911 | return sysfs_create_link(from, to, kobject_name(to)); | 784 | return sysfs_create_link(from, to, kobject_name(to)); |
912 | } | 785 | } |
913 | 786 | ||
914 | static void del_symlink(struct kobject *from, struct kobject *to) | 787 | static void del_symlink(struct kobject *from, struct kobject *to) |
915 | { | 788 | { |
916 | if (!from || !to) | ||
917 | return; | ||
918 | sysfs_remove_link(from, kobject_name(to)); | 789 | sysfs_remove_link(from, kobject_name(to)); |
919 | } | 790 | } |
920 | 791 | ||
921 | /* | ||
922 | * 'struct bd_holder' contains pointers to kobjects symlinked by | ||
923 | * bd_claim_by_kobject. | ||
924 | * It's connected to bd_holder_list which is protected by bdev->bd_sem. | ||
925 | */ | ||
926 | struct bd_holder { | ||
927 | struct list_head list; /* chain of holders of the bdev */ | ||
928 | int count; /* references from the holder */ | ||
929 | struct kobject *sdir; /* holder object, e.g. "/block/dm-0/slaves" */ | ||
930 | struct kobject *hdev; /* e.g. "/block/dm-0" */ | ||
931 | struct kobject *hdir; /* e.g. "/block/sda/holders" */ | ||
932 | struct kobject *sdev; /* e.g. "/block/sda" */ | ||
933 | }; | ||
934 | |||
935 | /* | ||
936 | * Get references of related kobjects at once. | ||
937 | * Returns 1 on success. 0 on failure. | ||
938 | * | ||
939 | * Should call bd_holder_release_dirs() after successful use. | ||
940 | */ | ||
941 | static int bd_holder_grab_dirs(struct block_device *bdev, | ||
942 | struct bd_holder *bo) | ||
943 | { | ||
944 | if (!bdev || !bo) | ||
945 | return 0; | ||
946 | |||
947 | bo->sdir = kobject_get(bo->sdir); | ||
948 | if (!bo->sdir) | ||
949 | return 0; | ||
950 | |||
951 | bo->hdev = kobject_get(bo->sdir->parent); | ||
952 | if (!bo->hdev) | ||
953 | goto fail_put_sdir; | ||
954 | |||
955 | bo->sdev = kobject_get(&part_to_dev(bdev->bd_part)->kobj); | ||
956 | if (!bo->sdev) | ||
957 | goto fail_put_hdev; | ||
958 | |||
959 | bo->hdir = kobject_get(bdev->bd_part->holder_dir); | ||
960 | if (!bo->hdir) | ||
961 | goto fail_put_sdev; | ||
962 | |||
963 | return 1; | ||
964 | |||
965 | fail_put_sdev: | ||
966 | kobject_put(bo->sdev); | ||
967 | fail_put_hdev: | ||
968 | kobject_put(bo->hdev); | ||
969 | fail_put_sdir: | ||
970 | kobject_put(bo->sdir); | ||
971 | |||
972 | return 0; | ||
973 | } | ||
974 | |||
975 | /* Put references of related kobjects at once. */ | ||
976 | static void bd_holder_release_dirs(struct bd_holder *bo) | ||
977 | { | ||
978 | kobject_put(bo->hdir); | ||
979 | kobject_put(bo->sdev); | ||
980 | kobject_put(bo->hdev); | ||
981 | kobject_put(bo->sdir); | ||
982 | } | ||
983 | |||
984 | static struct bd_holder *alloc_bd_holder(struct kobject *kobj) | ||
985 | { | ||
986 | struct bd_holder *bo; | ||
987 | |||
988 | bo = kzalloc(sizeof(*bo), GFP_KERNEL); | ||
989 | if (!bo) | ||
990 | return NULL; | ||
991 | |||
992 | bo->count = 1; | ||
993 | bo->sdir = kobj; | ||
994 | |||
995 | return bo; | ||
996 | } | ||
997 | |||
998 | static void free_bd_holder(struct bd_holder *bo) | ||
999 | { | ||
1000 | kfree(bo); | ||
1001 | } | ||
1002 | |||
1003 | /** | 792 | /** |
1004 | * find_bd_holder - find matching struct bd_holder from the block device | 793 | * bd_link_disk_holder - create symlinks between holding disk and slave bdev |
794 | * @bdev: the claimed slave bdev | ||
795 | * @disk: the holding disk | ||
1005 | * | 796 | * |
1006 | * @bdev: struct block device to be searched | 797 | * This functions creates the following sysfs symlinks. |
1007 | * @bo: target struct bd_holder | ||
1008 | * | ||
1009 | * Returns matching entry with @bo in @bdev->bd_holder_list. | ||
1010 | * If found, increment the reference count and return the pointer. | ||
1011 | * If not found, returns NULL. | ||
1012 | */ | ||
1013 | static struct bd_holder *find_bd_holder(struct block_device *bdev, | ||
1014 | struct bd_holder *bo) | ||
1015 | { | ||
1016 | struct bd_holder *tmp; | ||
1017 | |||
1018 | list_for_each_entry(tmp, &bdev->bd_holder_list, list) | ||
1019 | if (tmp->sdir == bo->sdir) { | ||
1020 | tmp->count++; | ||
1021 | return tmp; | ||
1022 | } | ||
1023 | |||
1024 | return NULL; | ||
1025 | } | ||
1026 | |||
1027 | /** | ||
1028 | * add_bd_holder - create sysfs symlinks for bd_claim() relationship | ||
1029 | * | ||
1030 | * @bdev: block device to be bd_claimed | ||
1031 | * @bo: preallocated and initialized by alloc_bd_holder() | ||
1032 | * | ||
1033 | * Add @bo to @bdev->bd_holder_list, create symlinks. | ||
1034 | * | ||
1035 | * Returns 0 if symlinks are created. | ||
1036 | * Returns -ve if something fails. | ||
1037 | */ | ||
1038 | static int add_bd_holder(struct block_device *bdev, struct bd_holder *bo) | ||
1039 | { | ||
1040 | int err; | ||
1041 | |||
1042 | if (!bo) | ||
1043 | return -EINVAL; | ||
1044 | |||
1045 | if (!bd_holder_grab_dirs(bdev, bo)) | ||
1046 | return -EBUSY; | ||
1047 | |||
1048 | err = add_symlink(bo->sdir, bo->sdev); | ||
1049 | if (err) | ||
1050 | return err; | ||
1051 | |||
1052 | err = add_symlink(bo->hdir, bo->hdev); | ||
1053 | if (err) { | ||
1054 | del_symlink(bo->sdir, bo->sdev); | ||
1055 | return err; | ||
1056 | } | ||
1057 | |||
1058 | list_add_tail(&bo->list, &bdev->bd_holder_list); | ||
1059 | return 0; | ||
1060 | } | ||
1061 | |||
1062 | /** | ||
1063 | * del_bd_holder - delete sysfs symlinks for bd_claim() relationship | ||
1064 | * | 798 | * |
1065 | * @bdev: block device to be bd_claimed | 799 | * - from "slaves" directory of the holder @disk to the claimed @bdev |
1066 | * @kobj: holder's kobject | 800 | * - from "holders" directory of the @bdev to the holder @disk |
1067 | * | 801 | * |
1068 | * If there is matching entry with @kobj in @bdev->bd_holder_list | 802 | * For example, if /dev/dm-0 maps to /dev/sda and disk for dm-0 is |
1069 | * and no other bd_claim() from the same kobject, | 803 | * passed to bd_link_disk_holder(), then: |
1070 | * remove the struct bd_holder from the list, delete symlinks for it. | ||
1071 | * | 804 | * |
1072 | * Returns a pointer to the struct bd_holder when it's removed from the list | 805 | * /sys/block/dm-0/slaves/sda --> /sys/block/sda |
1073 | * and ready to be freed. | 806 | * /sys/block/sda/holders/dm-0 --> /sys/block/dm-0 |
1074 | * Returns NULL if matching claim isn't found or there is other bd_claim() | ||
1075 | * by the same kobject. | ||
1076 | */ | ||
1077 | static struct bd_holder *del_bd_holder(struct block_device *bdev, | ||
1078 | struct kobject *kobj) | ||
1079 | { | ||
1080 | struct bd_holder *bo; | ||
1081 | |||
1082 | list_for_each_entry(bo, &bdev->bd_holder_list, list) { | ||
1083 | if (bo->sdir == kobj) { | ||
1084 | bo->count--; | ||
1085 | BUG_ON(bo->count < 0); | ||
1086 | if (!bo->count) { | ||
1087 | list_del(&bo->list); | ||
1088 | del_symlink(bo->sdir, bo->sdev); | ||
1089 | del_symlink(bo->hdir, bo->hdev); | ||
1090 | bd_holder_release_dirs(bo); | ||
1091 | return bo; | ||
1092 | } | ||
1093 | break; | ||
1094 | } | ||
1095 | } | ||
1096 | |||
1097 | return NULL; | ||
1098 | } | ||
1099 | |||
1100 | /** | ||
1101 | * bd_claim_by_kobject - bd_claim() with additional kobject signature | ||
1102 | * | 807 | * |
1103 | * @bdev: block device to be claimed | 808 | * The caller must have claimed @bdev before calling this function and |
1104 | * @holder: holder's signature | 809 | * ensure that both @bdev and @disk are valid during the creation and |
1105 | * @kobj: holder's kobject | 810 | * lifetime of these symlinks. |
1106 | * | 811 | * |
1107 | * Do bd_claim() and if it succeeds, create sysfs symlinks between | 812 | * CONTEXT: |
1108 | * the bdev and the holder's kobject. | 813 | * Might sleep. |
1109 | * Use bd_release_from_kobject() when relesing the claimed bdev. | ||
1110 | * | 814 | * |
1111 | * Returns 0 on success. (same as bd_claim()) | 815 | * RETURNS: |
1112 | * Returns errno on failure. | 816 | * 0 on success, -errno on failure. |
1113 | */ | 817 | */ |
1114 | static int bd_claim_by_kobject(struct block_device *bdev, void *holder, | 818 | int bd_link_disk_holder(struct block_device *bdev, struct gendisk *disk) |
1115 | struct kobject *kobj) | ||
1116 | { | 819 | { |
1117 | int err; | 820 | int ret = 0; |
1118 | struct bd_holder *bo, *found; | ||
1119 | |||
1120 | if (!kobj) | ||
1121 | return -EINVAL; | ||
1122 | |||
1123 | bo = alloc_bd_holder(kobj); | ||
1124 | if (!bo) | ||
1125 | return -ENOMEM; | ||
1126 | 821 | ||
1127 | mutex_lock(&bdev->bd_mutex); | 822 | mutex_lock(&bdev->bd_mutex); |
1128 | 823 | ||
1129 | err = bd_claim(bdev, holder); | 824 | WARN_ON_ONCE(!bdev->bd_holder || bdev->bd_holder_disk); |
1130 | if (err) | ||
1131 | goto fail; | ||
1132 | 825 | ||
1133 | found = find_bd_holder(bdev, bo); | 826 | /* FIXME: remove the following once add_disk() handles errors */ |
1134 | if (found) | 827 | if (WARN_ON(!disk->slave_dir || !bdev->bd_part->holder_dir)) |
1135 | goto fail; | 828 | goto out_unlock; |
1136 | 829 | ||
1137 | err = add_bd_holder(bdev, bo); | 830 | ret = add_symlink(disk->slave_dir, &part_to_dev(bdev->bd_part)->kobj); |
1138 | if (err) | 831 | if (ret) |
1139 | bd_release(bdev); | 832 | goto out_unlock; |
1140 | else | ||
1141 | bo = NULL; | ||
1142 | fail: | ||
1143 | mutex_unlock(&bdev->bd_mutex); | ||
1144 | free_bd_holder(bo); | ||
1145 | return err; | ||
1146 | } | ||
1147 | 833 | ||
1148 | /** | 834 | ret = add_symlink(bdev->bd_part->holder_dir, &disk_to_dev(disk)->kobj); |
1149 | * bd_release_from_kobject - bd_release() with additional kobject signature | 835 | if (ret) { |
1150 | * | 836 | del_symlink(disk->slave_dir, &part_to_dev(bdev->bd_part)->kobj); |
1151 | * @bdev: block device to be released | 837 | goto out_unlock; |
1152 | * @kobj: holder's kobject | 838 | } |
1153 | * | ||
1154 | * Do bd_release() and remove sysfs symlinks created by bd_claim_by_kobject(). | ||
1155 | */ | ||
1156 | static void bd_release_from_kobject(struct block_device *bdev, | ||
1157 | struct kobject *kobj) | ||
1158 | { | ||
1159 | if (!kobj) | ||
1160 | return; | ||
1161 | 839 | ||
1162 | mutex_lock(&bdev->bd_mutex); | 840 | bdev->bd_holder_disk = disk; |
1163 | bd_release(bdev); | 841 | out_unlock: |
1164 | free_bd_holder(del_bd_holder(bdev, kobj)); | ||
1165 | mutex_unlock(&bdev->bd_mutex); | 842 | mutex_unlock(&bdev->bd_mutex); |
843 | return ret; | ||
1166 | } | 844 | } |
845 | EXPORT_SYMBOL_GPL(bd_link_disk_holder); | ||
1167 | 846 | ||
1168 | /** | 847 | static void bd_unlink_disk_holder(struct block_device *bdev) |
1169 | * bd_claim_by_disk - wrapper function for bd_claim_by_kobject() | ||
1170 | * | ||
1171 | * @bdev: block device to be claimed | ||
1172 | * @holder: holder's signature | ||
1173 | * @disk: holder's gendisk | ||
1174 | * | ||
1175 | * Call bd_claim_by_kobject() with getting @disk->slave_dir. | ||
1176 | */ | ||
1177 | int bd_claim_by_disk(struct block_device *bdev, void *holder, | ||
1178 | struct gendisk *disk) | ||
1179 | { | 848 | { |
1180 | return bd_claim_by_kobject(bdev, holder, kobject_get(disk->slave_dir)); | 849 | struct gendisk *disk = bdev->bd_holder_disk; |
1181 | } | ||
1182 | EXPORT_SYMBOL_GPL(bd_claim_by_disk); | ||
1183 | 850 | ||
1184 | /** | 851 | bdev->bd_holder_disk = NULL; |
1185 | * bd_release_from_disk - wrapper function for bd_release_from_kobject() | 852 | if (!disk) |
1186 | * | 853 | return; |
1187 | * @bdev: block device to be claimed | ||
1188 | * @disk: holder's gendisk | ||
1189 | * | ||
1190 | * Call bd_release_from_kobject() and put @disk->slave_dir. | ||
1191 | */ | ||
1192 | void bd_release_from_disk(struct block_device *bdev, struct gendisk *disk) | ||
1193 | { | ||
1194 | bd_release_from_kobject(bdev, disk->slave_dir); | ||
1195 | kobject_put(disk->slave_dir); | ||
1196 | } | ||
1197 | EXPORT_SYMBOL_GPL(bd_release_from_disk); | ||
1198 | #endif | ||
1199 | 854 | ||
1200 | /* | 855 | del_symlink(disk->slave_dir, &part_to_dev(bdev->bd_part)->kobj); |
1201 | * Tries to open block device by device number. Use it ONLY if you | 856 | del_symlink(bdev->bd_part->holder_dir, &disk_to_dev(disk)->kobj); |
1202 | * really do not have anything better - i.e. when you are behind a | ||
1203 | * truly sucky interface and all you are given is a device number. _Never_ | ||
1204 | * to be used for internal purposes. If you ever need it - reconsider | ||
1205 | * your API. | ||
1206 | */ | ||
1207 | struct block_device *open_by_devnum(dev_t dev, fmode_t mode) | ||
1208 | { | ||
1209 | struct block_device *bdev = bdget(dev); | ||
1210 | int err = -ENOMEM; | ||
1211 | if (bdev) | ||
1212 | err = blkdev_get(bdev, mode); | ||
1213 | return err ? ERR_PTR(err) : bdev; | ||
1214 | } | 857 | } |
1215 | 858 | #else | |
1216 | EXPORT_SYMBOL(open_by_devnum); | 859 | static inline void bd_unlink_disk_holder(struct block_device *bdev) |
860 | { } | ||
861 | #endif | ||
1217 | 862 | ||
1218 | /** | 863 | /** |
1219 | * flush_disk - invalidates all buffer-cache entries on a disk | 864 | * flush_disk - invalidates all buffer-cache entries on a disk |
@@ -1309,10 +954,11 @@ int check_disk_change(struct block_device *bdev) | |||
1309 | { | 954 | { |
1310 | struct gendisk *disk = bdev->bd_disk; | 955 | struct gendisk *disk = bdev->bd_disk; |
1311 | const struct block_device_operations *bdops = disk->fops; | 956 | const struct block_device_operations *bdops = disk->fops; |
957 | unsigned int events; | ||
1312 | 958 | ||
1313 | if (!bdops->media_changed) | 959 | events = disk_clear_events(disk, DISK_EVENT_MEDIA_CHANGE | |
1314 | return 0; | 960 | DISK_EVENT_EJECT_REQUEST); |
1315 | if (!bdops->media_changed(bdev->bd_disk)) | 961 | if (!(events & DISK_EVENT_MEDIA_CHANGE)) |
1316 | return 0; | 962 | return 0; |
1317 | 963 | ||
1318 | flush_disk(bdev); | 964 | flush_disk(bdev); |
@@ -1475,17 +1121,171 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) | |||
1475 | return ret; | 1121 | return ret; |
1476 | } | 1122 | } |
1477 | 1123 | ||
1478 | int blkdev_get(struct block_device *bdev, fmode_t mode) | 1124 | /** |
1125 | * blkdev_get - open a block device | ||
1126 | * @bdev: block_device to open | ||
1127 | * @mode: FMODE_* mask | ||
1128 | * @holder: exclusive holder identifier | ||
1129 | * | ||
1130 | * Open @bdev with @mode. If @mode includes %FMODE_EXCL, @bdev is | ||
1131 | * open with exclusive access. Specifying %FMODE_EXCL with %NULL | ||
1132 | * @holder is invalid. Exclusive opens may nest for the same @holder. | ||
1133 | * | ||
1134 | * On success, the reference count of @bdev is unchanged. On failure, | ||
1135 | * @bdev is put. | ||
1136 | * | ||
1137 | * CONTEXT: | ||
1138 | * Might sleep. | ||
1139 | * | ||
1140 | * RETURNS: | ||
1141 | * 0 on success, -errno on failure. | ||
1142 | */ | ||
1143 | int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder) | ||
1479 | { | 1144 | { |
1480 | return __blkdev_get(bdev, mode, 0); | 1145 | struct block_device *whole = NULL; |
1146 | int res; | ||
1147 | |||
1148 | WARN_ON_ONCE((mode & FMODE_EXCL) && !holder); | ||
1149 | |||
1150 | if ((mode & FMODE_EXCL) && holder) { | ||
1151 | whole = bd_start_claiming(bdev, holder); | ||
1152 | if (IS_ERR(whole)) { | ||
1153 | bdput(bdev); | ||
1154 | return PTR_ERR(whole); | ||
1155 | } | ||
1156 | } | ||
1157 | |||
1158 | res = __blkdev_get(bdev, mode, 0); | ||
1159 | |||
1160 | /* __blkdev_get() may alter read only status, check it afterwards */ | ||
1161 | if (!res && (mode & FMODE_WRITE) && bdev_read_only(bdev)) { | ||
1162 | __blkdev_put(bdev, mode, 0); | ||
1163 | res = -EACCES; | ||
1164 | } | ||
1165 | |||
1166 | if (whole) { | ||
1167 | /* finish claiming */ | ||
1168 | mutex_lock(&bdev->bd_mutex); | ||
1169 | spin_lock(&bdev_lock); | ||
1170 | |||
1171 | if (!res) { | ||
1172 | BUG_ON(!bd_may_claim(bdev, whole, holder)); | ||
1173 | /* | ||
1174 | * Note that for a whole device bd_holders | ||
1175 | * will be incremented twice, and bd_holder | ||
1176 | * will be set to bd_may_claim before being | ||
1177 | * set to holder | ||
1178 | */ | ||
1179 | whole->bd_holders++; | ||
1180 | whole->bd_holder = bd_may_claim; | ||
1181 | bdev->bd_holders++; | ||
1182 | bdev->bd_holder = holder; | ||
1183 | } | ||
1184 | |||
1185 | /* tell others that we're done */ | ||
1186 | BUG_ON(whole->bd_claiming != holder); | ||
1187 | whole->bd_claiming = NULL; | ||
1188 | wake_up_bit(&whole->bd_claiming, 0); | ||
1189 | |||
1190 | spin_unlock(&bdev_lock); | ||
1191 | |||
1192 | /* | ||
1193 | * Block event polling for write claims. Any write | ||
1194 | * holder makes the write_holder state stick until all | ||
1195 | * are released. This is good enough and tracking | ||
1196 | * individual writeable reference is too fragile given | ||
1197 | * the way @mode is used in blkdev_get/put(). | ||
1198 | */ | ||
1199 | if (!res && (mode & FMODE_WRITE) && !bdev->bd_write_holder) { | ||
1200 | bdev->bd_write_holder = true; | ||
1201 | disk_block_events(bdev->bd_disk); | ||
1202 | } | ||
1203 | |||
1204 | mutex_unlock(&bdev->bd_mutex); | ||
1205 | bdput(whole); | ||
1206 | } | ||
1207 | |||
1208 | return res; | ||
1481 | } | 1209 | } |
1482 | EXPORT_SYMBOL(blkdev_get); | 1210 | EXPORT_SYMBOL(blkdev_get); |
1483 | 1211 | ||
1212 | /** | ||
1213 | * blkdev_get_by_path - open a block device by name | ||
1214 | * @path: path to the block device to open | ||
1215 | * @mode: FMODE_* mask | ||
1216 | * @holder: exclusive holder identifier | ||
1217 | * | ||
1218 | * Open the blockdevice described by the device file at @path. @mode | ||
1219 | * and @holder are identical to blkdev_get(). | ||
1220 | * | ||
1221 | * On success, the returned block_device has reference count of one. | ||
1222 | * | ||
1223 | * CONTEXT: | ||
1224 | * Might sleep. | ||
1225 | * | ||
1226 | * RETURNS: | ||
1227 | * Pointer to block_device on success, ERR_PTR(-errno) on failure. | ||
1228 | */ | ||
1229 | struct block_device *blkdev_get_by_path(const char *path, fmode_t mode, | ||
1230 | void *holder) | ||
1231 | { | ||
1232 | struct block_device *bdev; | ||
1233 | int err; | ||
1234 | |||
1235 | bdev = lookup_bdev(path); | ||
1236 | if (IS_ERR(bdev)) | ||
1237 | return bdev; | ||
1238 | |||
1239 | err = blkdev_get(bdev, mode, holder); | ||
1240 | if (err) | ||
1241 | return ERR_PTR(err); | ||
1242 | |||
1243 | return bdev; | ||
1244 | } | ||
1245 | EXPORT_SYMBOL(blkdev_get_by_path); | ||
1246 | |||
1247 | /** | ||
1248 | * blkdev_get_by_dev - open a block device by device number | ||
1249 | * @dev: device number of block device to open | ||
1250 | * @mode: FMODE_* mask | ||
1251 | * @holder: exclusive holder identifier | ||
1252 | * | ||
1253 | * Open the blockdevice described by device number @dev. @mode and | ||
1254 | * @holder are identical to blkdev_get(). | ||
1255 | * | ||
1256 | * Use it ONLY if you really do not have anything better - i.e. when | ||
1257 | * you are behind a truly sucky interface and all you are given is a | ||
1258 | * device number. _Never_ to be used for internal purposes. If you | ||
1259 | * ever need it - reconsider your API. | ||
1260 | * | ||
1261 | * On success, the returned block_device has reference count of one. | ||
1262 | * | ||
1263 | * CONTEXT: | ||
1264 | * Might sleep. | ||
1265 | * | ||
1266 | * RETURNS: | ||
1267 | * Pointer to block_device on success, ERR_PTR(-errno) on failure. | ||
1268 | */ | ||
1269 | struct block_device *blkdev_get_by_dev(dev_t dev, fmode_t mode, void *holder) | ||
1270 | { | ||
1271 | struct block_device *bdev; | ||
1272 | int err; | ||
1273 | |||
1274 | bdev = bdget(dev); | ||
1275 | if (!bdev) | ||
1276 | return ERR_PTR(-ENOMEM); | ||
1277 | |||
1278 | err = blkdev_get(bdev, mode, holder); | ||
1279 | if (err) | ||
1280 | return ERR_PTR(err); | ||
1281 | |||
1282 | return bdev; | ||
1283 | } | ||
1284 | EXPORT_SYMBOL(blkdev_get_by_dev); | ||
1285 | |||
1484 | static int blkdev_open(struct inode * inode, struct file * filp) | 1286 | static int blkdev_open(struct inode * inode, struct file * filp) |
1485 | { | 1287 | { |
1486 | struct block_device *whole = NULL; | ||
1487 | struct block_device *bdev; | 1288 | struct block_device *bdev; |
1488 | int res; | ||
1489 | 1289 | ||
1490 | /* | 1290 | /* |
1491 | * Preserve backwards compatibility and allow large file access | 1291 | * Preserve backwards compatibility and allow large file access |
@@ -1506,26 +1306,9 @@ static int blkdev_open(struct inode * inode, struct file * filp) | |||
1506 | if (bdev == NULL) | 1306 | if (bdev == NULL) |
1507 | return -ENOMEM; | 1307 | return -ENOMEM; |
1508 | 1308 | ||
1509 | if (filp->f_mode & FMODE_EXCL) { | ||
1510 | whole = bd_start_claiming(bdev, filp); | ||
1511 | if (IS_ERR(whole)) { | ||
1512 | bdput(bdev); | ||
1513 | return PTR_ERR(whole); | ||
1514 | } | ||
1515 | } | ||
1516 | |||
1517 | filp->f_mapping = bdev->bd_inode->i_mapping; | 1309 | filp->f_mapping = bdev->bd_inode->i_mapping; |
1518 | 1310 | ||
1519 | res = blkdev_get(bdev, filp->f_mode); | 1311 | return blkdev_get(bdev, filp->f_mode, filp); |
1520 | |||
1521 | if (whole) { | ||
1522 | if (res == 0) | ||
1523 | bd_finish_claiming(bdev, whole, filp); | ||
1524 | else | ||
1525 | bd_abort_claiming(whole, filp); | ||
1526 | } | ||
1527 | |||
1528 | return res; | ||
1529 | } | 1312 | } |
1530 | 1313 | ||
1531 | static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part) | 1314 | static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part) |
@@ -1539,6 +1322,7 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part) | |||
1539 | bdev->bd_part_count--; | 1322 | bdev->bd_part_count--; |
1540 | 1323 | ||
1541 | if (!--bdev->bd_openers) { | 1324 | if (!--bdev->bd_openers) { |
1325 | WARN_ON_ONCE(bdev->bd_holders); | ||
1542 | sync_blockdev(bdev); | 1326 | sync_blockdev(bdev); |
1543 | kill_bdev(bdev); | 1327 | kill_bdev(bdev); |
1544 | } | 1328 | } |
@@ -1569,6 +1353,45 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part) | |||
1569 | 1353 | ||
1570 | int blkdev_put(struct block_device *bdev, fmode_t mode) | 1354 | int blkdev_put(struct block_device *bdev, fmode_t mode) |
1571 | { | 1355 | { |
1356 | if (mode & FMODE_EXCL) { | ||
1357 | bool bdev_free; | ||
1358 | |||
1359 | /* | ||
1360 | * Release a claim on the device. The holder fields | ||
1361 | * are protected with bdev_lock. bd_mutex is to | ||
1362 | * synchronize disk_holder unlinking. | ||
1363 | */ | ||
1364 | mutex_lock(&bdev->bd_mutex); | ||
1365 | spin_lock(&bdev_lock); | ||
1366 | |||
1367 | WARN_ON_ONCE(--bdev->bd_holders < 0); | ||
1368 | WARN_ON_ONCE(--bdev->bd_contains->bd_holders < 0); | ||
1369 | |||
1370 | /* bd_contains might point to self, check in a separate step */ | ||
1371 | if ((bdev_free = !bdev->bd_holders)) | ||
1372 | bdev->bd_holder = NULL; | ||
1373 | if (!bdev->bd_contains->bd_holders) | ||
1374 | bdev->bd_contains->bd_holder = NULL; | ||
1375 | |||
1376 | spin_unlock(&bdev_lock); | ||
1377 | |||
1378 | /* | ||
1379 | * If this was the last claim, remove holder link and | ||
1380 | * unblock evpoll if it was a write holder. | ||
1381 | */ | ||
1382 | if (bdev_free) { | ||
1383 | bd_unlink_disk_holder(bdev); | ||
1384 | if (bdev->bd_write_holder) { | ||
1385 | disk_unblock_events(bdev->bd_disk); | ||
1386 | bdev->bd_write_holder = false; | ||
1387 | } else | ||
1388 | disk_check_events(bdev->bd_disk); | ||
1389 | } | ||
1390 | |||
1391 | mutex_unlock(&bdev->bd_mutex); | ||
1392 | } else | ||
1393 | disk_check_events(bdev->bd_disk); | ||
1394 | |||
1572 | return __blkdev_put(bdev, mode, 0); | 1395 | return __blkdev_put(bdev, mode, 0); |
1573 | } | 1396 | } |
1574 | EXPORT_SYMBOL(blkdev_put); | 1397 | EXPORT_SYMBOL(blkdev_put); |
@@ -1576,8 +1399,7 @@ EXPORT_SYMBOL(blkdev_put); | |||
1576 | static int blkdev_close(struct inode * inode, struct file * filp) | 1399 | static int blkdev_close(struct inode * inode, struct file * filp) |
1577 | { | 1400 | { |
1578 | struct block_device *bdev = I_BDEV(filp->f_mapping->host); | 1401 | struct block_device *bdev = I_BDEV(filp->f_mapping->host); |
1579 | if (bdev->bd_holder == filp) | 1402 | |
1580 | bd_release(bdev); | ||
1581 | return blkdev_put(bdev, filp->f_mode); | 1403 | return blkdev_put(bdev, filp->f_mode); |
1582 | } | 1404 | } |
1583 | 1405 | ||
@@ -1722,67 +1544,6 @@ fail: | |||
1722 | } | 1544 | } |
1723 | EXPORT_SYMBOL(lookup_bdev); | 1545 | EXPORT_SYMBOL(lookup_bdev); |
1724 | 1546 | ||
1725 | /** | ||
1726 | * open_bdev_exclusive - open a block device by name and set it up for use | ||
1727 | * | ||
1728 | * @path: special file representing the block device | ||
1729 | * @mode: FMODE_... combination to pass be used | ||
1730 | * @holder: owner for exclusion | ||
1731 | * | ||
1732 | * Open the blockdevice described by the special file at @path, claim it | ||
1733 | * for the @holder. | ||
1734 | */ | ||
1735 | struct block_device *open_bdev_exclusive(const char *path, fmode_t mode, void *holder) | ||
1736 | { | ||
1737 | struct block_device *bdev, *whole; | ||
1738 | int error; | ||
1739 | |||
1740 | bdev = lookup_bdev(path); | ||
1741 | if (IS_ERR(bdev)) | ||
1742 | return bdev; | ||
1743 | |||
1744 | whole = bd_start_claiming(bdev, holder); | ||
1745 | if (IS_ERR(whole)) { | ||
1746 | bdput(bdev); | ||
1747 | return whole; | ||
1748 | } | ||
1749 | |||
1750 | error = blkdev_get(bdev, mode); | ||
1751 | if (error) | ||
1752 | goto out_abort_claiming; | ||
1753 | |||
1754 | error = -EACCES; | ||
1755 | if ((mode & FMODE_WRITE) && bdev_read_only(bdev)) | ||
1756 | goto out_blkdev_put; | ||
1757 | |||
1758 | bd_finish_claiming(bdev, whole, holder); | ||
1759 | return bdev; | ||
1760 | |||
1761 | out_blkdev_put: | ||
1762 | blkdev_put(bdev, mode); | ||
1763 | out_abort_claiming: | ||
1764 | bd_abort_claiming(whole, holder); | ||
1765 | return ERR_PTR(error); | ||
1766 | } | ||
1767 | |||
1768 | EXPORT_SYMBOL(open_bdev_exclusive); | ||
1769 | |||
1770 | /** | ||
1771 | * close_bdev_exclusive - close a blockdevice opened by open_bdev_exclusive() | ||
1772 | * | ||
1773 | * @bdev: blockdevice to close | ||
1774 | * @mode: mode, must match that used to open. | ||
1775 | * | ||
1776 | * This is the counterpart to open_bdev_exclusive(). | ||
1777 | */ | ||
1778 | void close_bdev_exclusive(struct block_device *bdev, fmode_t mode) | ||
1779 | { | ||
1780 | bd_release(bdev); | ||
1781 | blkdev_put(bdev, mode); | ||
1782 | } | ||
1783 | |||
1784 | EXPORT_SYMBOL(close_bdev_exclusive); | ||
1785 | |||
1786 | int __invalidate_device(struct block_device *bdev) | 1547 | int __invalidate_device(struct block_device *bdev) |
1787 | { | 1548 | { |
1788 | struct super_block *sb = get_super(bdev); | 1549 | struct super_block *sb = get_super(bdev); |
diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c index 0ccf9a8afcdf..9786963b07e5 100644 --- a/fs/btrfs/export.c +++ b/fs/btrfs/export.c | |||
@@ -65,7 +65,6 @@ static struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid, | |||
65 | { | 65 | { |
66 | struct btrfs_fs_info *fs_info = btrfs_sb(sb)->fs_info; | 66 | struct btrfs_fs_info *fs_info = btrfs_sb(sb)->fs_info; |
67 | struct btrfs_root *root; | 67 | struct btrfs_root *root; |
68 | struct dentry *dentry; | ||
69 | struct inode *inode; | 68 | struct inode *inode; |
70 | struct btrfs_key key; | 69 | struct btrfs_key key; |
71 | int index; | 70 | int index; |
@@ -108,10 +107,7 @@ static struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid, | |||
108 | return ERR_PTR(-ESTALE); | 107 | return ERR_PTR(-ESTALE); |
109 | } | 108 | } |
110 | 109 | ||
111 | dentry = d_obtain_alias(inode); | 110 | return d_obtain_alias(inode); |
112 | if (!IS_ERR(dentry)) | ||
113 | d_set_d_op(dentry, &btrfs_dentry_operations); | ||
114 | return dentry; | ||
115 | fail: | 111 | fail: |
116 | srcu_read_unlock(&fs_info->subvol_srcu, index); | 112 | srcu_read_unlock(&fs_info->subvol_srcu, index); |
117 | return ERR_PTR(err); | 113 | return ERR_PTR(err); |
@@ -166,7 +162,6 @@ static struct dentry *btrfs_fh_to_dentry(struct super_block *sb, struct fid *fh, | |||
166 | static struct dentry *btrfs_get_parent(struct dentry *child) | 162 | static struct dentry *btrfs_get_parent(struct dentry *child) |
167 | { | 163 | { |
168 | struct inode *dir = child->d_inode; | 164 | struct inode *dir = child->d_inode; |
169 | struct dentry *dentry; | ||
170 | struct btrfs_root *root = BTRFS_I(dir)->root; | 165 | struct btrfs_root *root = BTRFS_I(dir)->root; |
171 | struct btrfs_path *path; | 166 | struct btrfs_path *path; |
172 | struct extent_buffer *leaf; | 167 | struct extent_buffer *leaf; |
@@ -223,10 +218,7 @@ static struct dentry *btrfs_get_parent(struct dentry *child) | |||
223 | 218 | ||
224 | key.type = BTRFS_INODE_ITEM_KEY; | 219 | key.type = BTRFS_INODE_ITEM_KEY; |
225 | key.offset = 0; | 220 | key.offset = 0; |
226 | dentry = d_obtain_alias(btrfs_iget(root->fs_info->sb, &key, root, NULL)); | 221 | return d_obtain_alias(btrfs_iget(root->fs_info->sb, &key, root, NULL)); |
227 | if (!IS_ERR(dentry)) | ||
228 | d_set_d_op(dentry, &btrfs_dentry_operations); | ||
229 | return dentry; | ||
230 | fail: | 222 | fail: |
231 | btrfs_free_path(path); | 223 | btrfs_free_path(path); |
232 | return ERR_PTR(ret); | 224 | return ERR_PTR(ret); |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index a0ff46a47895..a3798a3aa0d2 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -4084,8 +4084,6 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) | |||
4084 | int index; | 4084 | int index; |
4085 | int ret; | 4085 | int ret; |
4086 | 4086 | ||
4087 | d_set_d_op(dentry, &btrfs_dentry_operations); | ||
4088 | |||
4089 | if (dentry->d_name.len > BTRFS_NAME_LEN) | 4087 | if (dentry->d_name.len > BTRFS_NAME_LEN) |
4090 | return ERR_PTR(-ENAMETOOLONG); | 4088 | return ERR_PTR(-ENAMETOOLONG); |
4091 | 4089 | ||
@@ -7117,6 +7115,10 @@ static long btrfs_fallocate(struct inode *inode, int mode, | |||
7117 | alloc_start = offset & ~mask; | 7115 | alloc_start = offset & ~mask; |
7118 | alloc_end = (offset + len + mask) & ~mask; | 7116 | alloc_end = (offset + len + mask) & ~mask; |
7119 | 7117 | ||
7118 | /* We only support the FALLOC_FL_KEEP_SIZE mode */ | ||
7119 | if (mode && (mode != FALLOC_FL_KEEP_SIZE)) | ||
7120 | return -EOPNOTSUPP; | ||
7121 | |||
7120 | /* | 7122 | /* |
7121 | * wait for ordered IO before we have any locks. We'll loop again | 7123 | * wait for ordered IO before we have any locks. We'll loop again |
7122 | * below with the locks held. | 7124 | * below with the locks held. |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 883c6fa1367e..22acdaa78ce1 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -460,6 +460,7 @@ static int btrfs_fill_super(struct super_block *sb, | |||
460 | sb->s_maxbytes = MAX_LFS_FILESIZE; | 460 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
461 | sb->s_magic = BTRFS_SUPER_MAGIC; | 461 | sb->s_magic = BTRFS_SUPER_MAGIC; |
462 | sb->s_op = &btrfs_super_ops; | 462 | sb->s_op = &btrfs_super_ops; |
463 | sb->s_d_op = &btrfs_dentry_operations; | ||
463 | sb->s_export_op = &btrfs_export_ops; | 464 | sb->s_export_op = &btrfs_export_ops; |
464 | sb->s_xattr = btrfs_xattr_handlers; | 465 | sb->s_xattr = btrfs_xattr_handlers; |
465 | sb->s_time_gran = 1; | 466 | sb->s_time_gran = 1; |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 6b9884507837..1718e1a5c320 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -493,7 +493,7 @@ again: | |||
493 | continue; | 493 | continue; |
494 | 494 | ||
495 | if (device->bdev) { | 495 | if (device->bdev) { |
496 | close_bdev_exclusive(device->bdev, device->mode); | 496 | blkdev_put(device->bdev, device->mode); |
497 | device->bdev = NULL; | 497 | device->bdev = NULL; |
498 | fs_devices->open_devices--; | 498 | fs_devices->open_devices--; |
499 | } | 499 | } |
@@ -527,7 +527,7 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) | |||
527 | 527 | ||
528 | list_for_each_entry(device, &fs_devices->devices, dev_list) { | 528 | list_for_each_entry(device, &fs_devices->devices, dev_list) { |
529 | if (device->bdev) { | 529 | if (device->bdev) { |
530 | close_bdev_exclusive(device->bdev, device->mode); | 530 | blkdev_put(device->bdev, device->mode); |
531 | fs_devices->open_devices--; | 531 | fs_devices->open_devices--; |
532 | } | 532 | } |
533 | if (device->writeable) { | 533 | if (device->writeable) { |
@@ -584,13 +584,15 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, | |||
584 | int seeding = 1; | 584 | int seeding = 1; |
585 | int ret = 0; | 585 | int ret = 0; |
586 | 586 | ||
587 | flags |= FMODE_EXCL; | ||
588 | |||
587 | list_for_each_entry(device, head, dev_list) { | 589 | list_for_each_entry(device, head, dev_list) { |
588 | if (device->bdev) | 590 | if (device->bdev) |
589 | continue; | 591 | continue; |
590 | if (!device->name) | 592 | if (!device->name) |
591 | continue; | 593 | continue; |
592 | 594 | ||
593 | bdev = open_bdev_exclusive(device->name, flags, holder); | 595 | bdev = blkdev_get_by_path(device->name, flags, holder); |
594 | if (IS_ERR(bdev)) { | 596 | if (IS_ERR(bdev)) { |
595 | printk(KERN_INFO "open %s failed\n", device->name); | 597 | printk(KERN_INFO "open %s failed\n", device->name); |
596 | goto error; | 598 | goto error; |
@@ -642,7 +644,7 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, | |||
642 | error_brelse: | 644 | error_brelse: |
643 | brelse(bh); | 645 | brelse(bh); |
644 | error_close: | 646 | error_close: |
645 | close_bdev_exclusive(bdev, FMODE_READ); | 647 | blkdev_put(bdev, flags); |
646 | error: | 648 | error: |
647 | continue; | 649 | continue; |
648 | } | 650 | } |
@@ -688,7 +690,8 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder, | |||
688 | 690 | ||
689 | mutex_lock(&uuid_mutex); | 691 | mutex_lock(&uuid_mutex); |
690 | 692 | ||
691 | bdev = open_bdev_exclusive(path, flags, holder); | 693 | flags |= FMODE_EXCL; |
694 | bdev = blkdev_get_by_path(path, flags, holder); | ||
692 | 695 | ||
693 | if (IS_ERR(bdev)) { | 696 | if (IS_ERR(bdev)) { |
694 | ret = PTR_ERR(bdev); | 697 | ret = PTR_ERR(bdev); |
@@ -720,7 +723,7 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder, | |||
720 | 723 | ||
721 | brelse(bh); | 724 | brelse(bh); |
722 | error_close: | 725 | error_close: |
723 | close_bdev_exclusive(bdev, flags); | 726 | blkdev_put(bdev, flags); |
724 | error: | 727 | error: |
725 | mutex_unlock(&uuid_mutex); | 728 | mutex_unlock(&uuid_mutex); |
726 | return ret; | 729 | return ret; |
@@ -1183,8 +1186,8 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) | |||
1183 | goto out; | 1186 | goto out; |
1184 | } | 1187 | } |
1185 | } else { | 1188 | } else { |
1186 | bdev = open_bdev_exclusive(device_path, FMODE_READ, | 1189 | bdev = blkdev_get_by_path(device_path, FMODE_READ | FMODE_EXCL, |
1187 | root->fs_info->bdev_holder); | 1190 | root->fs_info->bdev_holder); |
1188 | if (IS_ERR(bdev)) { | 1191 | if (IS_ERR(bdev)) { |
1189 | ret = PTR_ERR(bdev); | 1192 | ret = PTR_ERR(bdev); |
1190 | goto out; | 1193 | goto out; |
@@ -1251,7 +1254,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) | |||
1251 | root->fs_info->fs_devices->latest_bdev = next_device->bdev; | 1254 | root->fs_info->fs_devices->latest_bdev = next_device->bdev; |
1252 | 1255 | ||
1253 | if (device->bdev) { | 1256 | if (device->bdev) { |
1254 | close_bdev_exclusive(device->bdev, device->mode); | 1257 | blkdev_put(device->bdev, device->mode); |
1255 | device->bdev = NULL; | 1258 | device->bdev = NULL; |
1256 | device->fs_devices->open_devices--; | 1259 | device->fs_devices->open_devices--; |
1257 | } | 1260 | } |
@@ -1294,7 +1297,7 @@ error_brelse: | |||
1294 | brelse(bh); | 1297 | brelse(bh); |
1295 | error_close: | 1298 | error_close: |
1296 | if (bdev) | 1299 | if (bdev) |
1297 | close_bdev_exclusive(bdev, FMODE_READ); | 1300 | blkdev_put(bdev, FMODE_READ | FMODE_EXCL); |
1298 | out: | 1301 | out: |
1299 | mutex_unlock(&root->fs_info->volume_mutex); | 1302 | mutex_unlock(&root->fs_info->volume_mutex); |
1300 | mutex_unlock(&uuid_mutex); | 1303 | mutex_unlock(&uuid_mutex); |
@@ -1446,7 +1449,8 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
1446 | if ((sb->s_flags & MS_RDONLY) && !root->fs_info->fs_devices->seeding) | 1449 | if ((sb->s_flags & MS_RDONLY) && !root->fs_info->fs_devices->seeding) |
1447 | return -EINVAL; | 1450 | return -EINVAL; |
1448 | 1451 | ||
1449 | bdev = open_bdev_exclusive(device_path, 0, root->fs_info->bdev_holder); | 1452 | bdev = blkdev_get_by_path(device_path, FMODE_EXCL, |
1453 | root->fs_info->bdev_holder); | ||
1450 | if (IS_ERR(bdev)) | 1454 | if (IS_ERR(bdev)) |
1451 | return PTR_ERR(bdev); | 1455 | return PTR_ERR(bdev); |
1452 | 1456 | ||
@@ -1572,7 +1576,7 @@ out: | |||
1572 | mutex_unlock(&root->fs_info->volume_mutex); | 1576 | mutex_unlock(&root->fs_info->volume_mutex); |
1573 | return ret; | 1577 | return ret; |
1574 | error: | 1578 | error: |
1575 | close_bdev_exclusive(bdev, 0); | 1579 | blkdev_put(bdev, FMODE_EXCL); |
1576 | if (seeding_dev) { | 1580 | if (seeding_dev) { |
1577 | mutex_unlock(&uuid_mutex); | 1581 | mutex_unlock(&uuid_mutex); |
1578 | up_write(&sb->s_umount); | 1582 | up_write(&sb->s_umount); |
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index 2740db49eb04..1be781079450 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h | |||
@@ -50,7 +50,7 @@ struct btrfs_device { | |||
50 | 50 | ||
51 | struct block_device *bdev; | 51 | struct block_device *bdev; |
52 | 52 | ||
53 | /* the mode sent to open_bdev_exclusive */ | 53 | /* the mode sent to blkdev_get */ |
54 | fmode_t mode; | 54 | fmode_t mode; |
55 | 55 | ||
56 | char *name; | 56 | char *name; |
diff --git a/fs/ceph/Makefile b/fs/ceph/Makefile index 9e6c4f2e8ff1..bd352125e829 100644 --- a/fs/ceph/Makefile +++ b/fs/ceph/Makefile | |||
@@ -2,31 +2,10 @@ | |||
2 | # Makefile for CEPH filesystem. | 2 | # Makefile for CEPH filesystem. |
3 | # | 3 | # |
4 | 4 | ||
5 | ifneq ($(KERNELRELEASE),) | ||
6 | |||
7 | obj-$(CONFIG_CEPH_FS) += ceph.o | 5 | obj-$(CONFIG_CEPH_FS) += ceph.o |
8 | 6 | ||
9 | ceph-objs := super.o inode.o dir.o file.o locks.o addr.o ioctl.o \ | 7 | ceph-y := super.o inode.o dir.o file.o locks.o addr.o ioctl.o \ |
10 | export.o caps.o snap.o xattr.o \ | 8 | export.o caps.o snap.o xattr.o \ |
11 | mds_client.o mdsmap.o strings.o ceph_frag.o \ | 9 | mds_client.o mdsmap.o strings.o ceph_frag.o \ |
12 | debugfs.o | 10 | debugfs.o |
13 | 11 | ||
14 | else | ||
15 | #Otherwise we were called directly from the command | ||
16 | # line; invoke the kernel build system. | ||
17 | |||
18 | KERNELDIR ?= /lib/modules/$(shell uname -r)/build | ||
19 | PWD := $(shell pwd) | ||
20 | |||
21 | default: all | ||
22 | |||
23 | all: | ||
24 | $(MAKE) -C $(KERNELDIR) M=$(PWD) CONFIG_CEPH_FS=m modules | ||
25 | |||
26 | modules_install: | ||
27 | $(MAKE) -C $(KERNELDIR) M=$(PWD) CONFIG_CEPH_FS=m modules_install | ||
28 | |||
29 | clean: | ||
30 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean | ||
31 | |||
32 | endif | ||
diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c index 7ae1b3d55b58..08f65faac112 100644 --- a/fs/ceph/debugfs.c +++ b/fs/ceph/debugfs.c | |||
@@ -60,10 +60,13 @@ static int mdsc_show(struct seq_file *s, void *p) | |||
60 | for (rp = rb_first(&mdsc->request_tree); rp; rp = rb_next(rp)) { | 60 | for (rp = rb_first(&mdsc->request_tree); rp; rp = rb_next(rp)) { |
61 | req = rb_entry(rp, struct ceph_mds_request, r_node); | 61 | req = rb_entry(rp, struct ceph_mds_request, r_node); |
62 | 62 | ||
63 | if (req->r_request) | 63 | if (req->r_request && req->r_session) |
64 | seq_printf(s, "%lld\tmds%d\t", req->r_tid, req->r_mds); | 64 | seq_printf(s, "%lld\tmds%d\t", req->r_tid, |
65 | else | 65 | req->r_session->s_mds); |
66 | else if (!req->r_request) | ||
66 | seq_printf(s, "%lld\t(no request)\t", req->r_tid); | 67 | seq_printf(s, "%lld\t(no request)\t", req->r_tid); |
68 | else | ||
69 | seq_printf(s, "%lld\t(no session)\t", req->r_tid); | ||
67 | 70 | ||
68 | seq_printf(s, "%s", ceph_mds_op_name(req->r_op)); | 71 | seq_printf(s, "%s", ceph_mds_op_name(req->r_op)); |
69 | 72 | ||
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index fa7ca04ee816..0bc68de8edd7 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -1224,6 +1224,26 @@ void ceph_dentry_lru_del(struct dentry *dn) | |||
1224 | } | 1224 | } |
1225 | } | 1225 | } |
1226 | 1226 | ||
1227 | /* | ||
1228 | * Return name hash for a given dentry. This is dependent on | ||
1229 | * the parent directory's hash function. | ||
1230 | */ | ||
1231 | unsigned ceph_dentry_hash(struct dentry *dn) | ||
1232 | { | ||
1233 | struct inode *dir = dn->d_parent->d_inode; | ||
1234 | struct ceph_inode_info *dci = ceph_inode(dir); | ||
1235 | |||
1236 | switch (dci->i_dir_layout.dl_dir_hash) { | ||
1237 | case 0: /* for backward compat */ | ||
1238 | case CEPH_STR_HASH_LINUX: | ||
1239 | return dn->d_name.hash; | ||
1240 | |||
1241 | default: | ||
1242 | return ceph_str_hash(dci->i_dir_layout.dl_dir_hash, | ||
1243 | dn->d_name.name, dn->d_name.len); | ||
1244 | } | ||
1245 | } | ||
1246 | |||
1227 | const struct file_operations ceph_dir_fops = { | 1247 | const struct file_operations ceph_dir_fops = { |
1228 | .read = ceph_read_dir, | 1248 | .read = ceph_read_dir, |
1229 | .readdir = ceph_readdir, | 1249 | .readdir = ceph_readdir, |
diff --git a/fs/ceph/export.c b/fs/ceph/export.c index 2297d9426992..e41056174bf8 100644 --- a/fs/ceph/export.c +++ b/fs/ceph/export.c | |||
@@ -59,7 +59,7 @@ static int ceph_encode_fh(struct dentry *dentry, u32 *rawfh, int *max_len, | |||
59 | dout("encode_fh %p connectable\n", dentry); | 59 | dout("encode_fh %p connectable\n", dentry); |
60 | cfh->ino = ceph_ino(dentry->d_inode); | 60 | cfh->ino = ceph_ino(dentry->d_inode); |
61 | cfh->parent_ino = ceph_ino(parent->d_inode); | 61 | cfh->parent_ino = ceph_ino(parent->d_inode); |
62 | cfh->parent_name_hash = parent->d_name.hash; | 62 | cfh->parent_name_hash = ceph_dentry_hash(parent); |
63 | *max_len = connected_handle_length; | 63 | *max_len = connected_handle_length; |
64 | type = 2; | 64 | type = 2; |
65 | } else if (*max_len >= handle_length) { | 65 | } else if (*max_len >= handle_length) { |
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index e61de4f7b99d..e835eff551e3 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
@@ -297,6 +297,8 @@ struct inode *ceph_alloc_inode(struct super_block *sb) | |||
297 | ci->i_release_count = 0; | 297 | ci->i_release_count = 0; |
298 | ci->i_symlink = NULL; | 298 | ci->i_symlink = NULL; |
299 | 299 | ||
300 | memset(&ci->i_dir_layout, 0, sizeof(ci->i_dir_layout)); | ||
301 | |||
300 | ci->i_fragtree = RB_ROOT; | 302 | ci->i_fragtree = RB_ROOT; |
301 | mutex_init(&ci->i_fragtree_mutex); | 303 | mutex_init(&ci->i_fragtree_mutex); |
302 | 304 | ||
@@ -689,6 +691,8 @@ static int fill_inode(struct inode *inode, | |||
689 | inode->i_op = &ceph_dir_iops; | 691 | inode->i_op = &ceph_dir_iops; |
690 | inode->i_fop = &ceph_dir_fops; | 692 | inode->i_fop = &ceph_dir_fops; |
691 | 693 | ||
694 | ci->i_dir_layout = iinfo->dir_layout; | ||
695 | |||
692 | ci->i_files = le64_to_cpu(info->files); | 696 | ci->i_files = le64_to_cpu(info->files); |
693 | ci->i_subdirs = le64_to_cpu(info->subdirs); | 697 | ci->i_subdirs = le64_to_cpu(info->subdirs); |
694 | ci->i_rbytes = le64_to_cpu(info->rbytes); | 698 | ci->i_rbytes = le64_to_cpu(info->rbytes); |
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index a50fca1e03be..1e30d194a8e3 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -60,7 +60,8 @@ static const struct ceph_connection_operations mds_con_ops; | |||
60 | * parse individual inode info | 60 | * parse individual inode info |
61 | */ | 61 | */ |
62 | static int parse_reply_info_in(void **p, void *end, | 62 | static int parse_reply_info_in(void **p, void *end, |
63 | struct ceph_mds_reply_info_in *info) | 63 | struct ceph_mds_reply_info_in *info, |
64 | int features) | ||
64 | { | 65 | { |
65 | int err = -EIO; | 66 | int err = -EIO; |
66 | 67 | ||
@@ -74,6 +75,12 @@ static int parse_reply_info_in(void **p, void *end, | |||
74 | info->symlink = *p; | 75 | info->symlink = *p; |
75 | *p += info->symlink_len; | 76 | *p += info->symlink_len; |
76 | 77 | ||
78 | if (features & CEPH_FEATURE_DIRLAYOUTHASH) | ||
79 | ceph_decode_copy_safe(p, end, &info->dir_layout, | ||
80 | sizeof(info->dir_layout), bad); | ||
81 | else | ||
82 | memset(&info->dir_layout, 0, sizeof(info->dir_layout)); | ||
83 | |||
77 | ceph_decode_32_safe(p, end, info->xattr_len, bad); | 84 | ceph_decode_32_safe(p, end, info->xattr_len, bad); |
78 | ceph_decode_need(p, end, info->xattr_len, bad); | 85 | ceph_decode_need(p, end, info->xattr_len, bad); |
79 | info->xattr_data = *p; | 86 | info->xattr_data = *p; |
@@ -88,12 +95,13 @@ bad: | |||
88 | * target inode. | 95 | * target inode. |
89 | */ | 96 | */ |
90 | static int parse_reply_info_trace(void **p, void *end, | 97 | static int parse_reply_info_trace(void **p, void *end, |
91 | struct ceph_mds_reply_info_parsed *info) | 98 | struct ceph_mds_reply_info_parsed *info, |
99 | int features) | ||
92 | { | 100 | { |
93 | int err; | 101 | int err; |
94 | 102 | ||
95 | if (info->head->is_dentry) { | 103 | if (info->head->is_dentry) { |
96 | err = parse_reply_info_in(p, end, &info->diri); | 104 | err = parse_reply_info_in(p, end, &info->diri, features); |
97 | if (err < 0) | 105 | if (err < 0) |
98 | goto out_bad; | 106 | goto out_bad; |
99 | 107 | ||
@@ -114,7 +122,7 @@ static int parse_reply_info_trace(void **p, void *end, | |||
114 | } | 122 | } |
115 | 123 | ||
116 | if (info->head->is_target) { | 124 | if (info->head->is_target) { |
117 | err = parse_reply_info_in(p, end, &info->targeti); | 125 | err = parse_reply_info_in(p, end, &info->targeti, features); |
118 | if (err < 0) | 126 | if (err < 0) |
119 | goto out_bad; | 127 | goto out_bad; |
120 | } | 128 | } |
@@ -134,7 +142,8 @@ out_bad: | |||
134 | * parse readdir results | 142 | * parse readdir results |
135 | */ | 143 | */ |
136 | static int parse_reply_info_dir(void **p, void *end, | 144 | static int parse_reply_info_dir(void **p, void *end, |
137 | struct ceph_mds_reply_info_parsed *info) | 145 | struct ceph_mds_reply_info_parsed *info, |
146 | int features) | ||
138 | { | 147 | { |
139 | u32 num, i = 0; | 148 | u32 num, i = 0; |
140 | int err; | 149 | int err; |
@@ -182,7 +191,7 @@ static int parse_reply_info_dir(void **p, void *end, | |||
182 | *p += sizeof(struct ceph_mds_reply_lease); | 191 | *p += sizeof(struct ceph_mds_reply_lease); |
183 | 192 | ||
184 | /* inode */ | 193 | /* inode */ |
185 | err = parse_reply_info_in(p, end, &info->dir_in[i]); | 194 | err = parse_reply_info_in(p, end, &info->dir_in[i], features); |
186 | if (err < 0) | 195 | if (err < 0) |
187 | goto out_bad; | 196 | goto out_bad; |
188 | i++; | 197 | i++; |
@@ -205,7 +214,8 @@ out_bad: | |||
205 | * parse fcntl F_GETLK results | 214 | * parse fcntl F_GETLK results |
206 | */ | 215 | */ |
207 | static int parse_reply_info_filelock(void **p, void *end, | 216 | static int parse_reply_info_filelock(void **p, void *end, |
208 | struct ceph_mds_reply_info_parsed *info) | 217 | struct ceph_mds_reply_info_parsed *info, |
218 | int features) | ||
209 | { | 219 | { |
210 | if (*p + sizeof(*info->filelock_reply) > end) | 220 | if (*p + sizeof(*info->filelock_reply) > end) |
211 | goto bad; | 221 | goto bad; |
@@ -225,19 +235,21 @@ bad: | |||
225 | * parse extra results | 235 | * parse extra results |
226 | */ | 236 | */ |
227 | static int parse_reply_info_extra(void **p, void *end, | 237 | static int parse_reply_info_extra(void **p, void *end, |
228 | struct ceph_mds_reply_info_parsed *info) | 238 | struct ceph_mds_reply_info_parsed *info, |
239 | int features) | ||
229 | { | 240 | { |
230 | if (info->head->op == CEPH_MDS_OP_GETFILELOCK) | 241 | if (info->head->op == CEPH_MDS_OP_GETFILELOCK) |
231 | return parse_reply_info_filelock(p, end, info); | 242 | return parse_reply_info_filelock(p, end, info, features); |
232 | else | 243 | else |
233 | return parse_reply_info_dir(p, end, info); | 244 | return parse_reply_info_dir(p, end, info, features); |
234 | } | 245 | } |
235 | 246 | ||
236 | /* | 247 | /* |
237 | * parse entire mds reply | 248 | * parse entire mds reply |
238 | */ | 249 | */ |
239 | static int parse_reply_info(struct ceph_msg *msg, | 250 | static int parse_reply_info(struct ceph_msg *msg, |
240 | struct ceph_mds_reply_info_parsed *info) | 251 | struct ceph_mds_reply_info_parsed *info, |
252 | int features) | ||
241 | { | 253 | { |
242 | void *p, *end; | 254 | void *p, *end; |
243 | u32 len; | 255 | u32 len; |
@@ -250,7 +262,7 @@ static int parse_reply_info(struct ceph_msg *msg, | |||
250 | /* trace */ | 262 | /* trace */ |
251 | ceph_decode_32_safe(&p, end, len, bad); | 263 | ceph_decode_32_safe(&p, end, len, bad); |
252 | if (len > 0) { | 264 | if (len > 0) { |
253 | err = parse_reply_info_trace(&p, p+len, info); | 265 | err = parse_reply_info_trace(&p, p+len, info, features); |
254 | if (err < 0) | 266 | if (err < 0) |
255 | goto out_bad; | 267 | goto out_bad; |
256 | } | 268 | } |
@@ -258,7 +270,7 @@ static int parse_reply_info(struct ceph_msg *msg, | |||
258 | /* extra */ | 270 | /* extra */ |
259 | ceph_decode_32_safe(&p, end, len, bad); | 271 | ceph_decode_32_safe(&p, end, len, bad); |
260 | if (len > 0) { | 272 | if (len > 0) { |
261 | err = parse_reply_info_extra(&p, p+len, info); | 273 | err = parse_reply_info_extra(&p, p+len, info, features); |
262 | if (err < 0) | 274 | if (err < 0) |
263 | goto out_bad; | 275 | goto out_bad; |
264 | } | 276 | } |
@@ -654,7 +666,7 @@ static int __choose_mds(struct ceph_mds_client *mdsc, | |||
654 | } else { | 666 | } else { |
655 | /* dir + name */ | 667 | /* dir + name */ |
656 | inode = dir; | 668 | inode = dir; |
657 | hash = req->r_dentry->d_name.hash; | 669 | hash = ceph_dentry_hash(req->r_dentry); |
658 | is_hash = true; | 670 | is_hash = true; |
659 | } | 671 | } |
660 | } | 672 | } |
@@ -1693,7 +1705,6 @@ static int __prepare_send_request(struct ceph_mds_client *mdsc, | |||
1693 | struct ceph_msg *msg; | 1705 | struct ceph_msg *msg; |
1694 | int flags = 0; | 1706 | int flags = 0; |
1695 | 1707 | ||
1696 | req->r_mds = mds; | ||
1697 | req->r_attempts++; | 1708 | req->r_attempts++; |
1698 | if (req->r_inode) { | 1709 | if (req->r_inode) { |
1699 | struct ceph_cap *cap = | 1710 | struct ceph_cap *cap = |
@@ -1780,6 +1791,8 @@ static int __do_request(struct ceph_mds_client *mdsc, | |||
1780 | goto finish; | 1791 | goto finish; |
1781 | } | 1792 | } |
1782 | 1793 | ||
1794 | put_request_session(req); | ||
1795 | |||
1783 | mds = __choose_mds(mdsc, req); | 1796 | mds = __choose_mds(mdsc, req); |
1784 | if (mds < 0 || | 1797 | if (mds < 0 || |
1785 | ceph_mdsmap_get_state(mdsc->mdsmap, mds) < CEPH_MDS_STATE_ACTIVE) { | 1798 | ceph_mdsmap_get_state(mdsc->mdsmap, mds) < CEPH_MDS_STATE_ACTIVE) { |
@@ -1797,6 +1810,8 @@ static int __do_request(struct ceph_mds_client *mdsc, | |||
1797 | goto finish; | 1810 | goto finish; |
1798 | } | 1811 | } |
1799 | } | 1812 | } |
1813 | req->r_session = get_session(session); | ||
1814 | |||
1800 | dout("do_request mds%d session %p state %s\n", mds, session, | 1815 | dout("do_request mds%d session %p state %s\n", mds, session, |
1801 | session_state_name(session->s_state)); | 1816 | session_state_name(session->s_state)); |
1802 | if (session->s_state != CEPH_MDS_SESSION_OPEN && | 1817 | if (session->s_state != CEPH_MDS_SESSION_OPEN && |
@@ -1809,7 +1824,6 @@ static int __do_request(struct ceph_mds_client *mdsc, | |||
1809 | } | 1824 | } |
1810 | 1825 | ||
1811 | /* send request */ | 1826 | /* send request */ |
1812 | req->r_session = get_session(session); | ||
1813 | req->r_resend_mds = -1; /* forget any previous mds hint */ | 1827 | req->r_resend_mds = -1; /* forget any previous mds hint */ |
1814 | 1828 | ||
1815 | if (req->r_request_started == 0) /* note request start time */ | 1829 | if (req->r_request_started == 0) /* note request start time */ |
@@ -1863,7 +1877,6 @@ static void kick_requests(struct ceph_mds_client *mdsc, int mds) | |||
1863 | if (req->r_session && | 1877 | if (req->r_session && |
1864 | req->r_session->s_mds == mds) { | 1878 | req->r_session->s_mds == mds) { |
1865 | dout(" kicking tid %llu\n", req->r_tid); | 1879 | dout(" kicking tid %llu\n", req->r_tid); |
1866 | put_request_session(req); | ||
1867 | __do_request(mdsc, req); | 1880 | __do_request(mdsc, req); |
1868 | } | 1881 | } |
1869 | } | 1882 | } |
@@ -2056,8 +2069,11 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) | |||
2056 | goto out; | 2069 | goto out; |
2057 | } else { | 2070 | } else { |
2058 | struct ceph_inode_info *ci = ceph_inode(req->r_inode); | 2071 | struct ceph_inode_info *ci = ceph_inode(req->r_inode); |
2059 | struct ceph_cap *cap = | 2072 | struct ceph_cap *cap = NULL; |
2060 | ceph_get_cap_for_mds(ci, req->r_mds);; | 2073 | |
2074 | if (req->r_session) | ||
2075 | cap = ceph_get_cap_for_mds(ci, | ||
2076 | req->r_session->s_mds); | ||
2061 | 2077 | ||
2062 | dout("already using auth"); | 2078 | dout("already using auth"); |
2063 | if ((!cap || cap != ci->i_auth_cap) || | 2079 | if ((!cap || cap != ci->i_auth_cap) || |
@@ -2101,7 +2117,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) | |||
2101 | 2117 | ||
2102 | dout("handle_reply tid %lld result %d\n", tid, result); | 2118 | dout("handle_reply tid %lld result %d\n", tid, result); |
2103 | rinfo = &req->r_reply_info; | 2119 | rinfo = &req->r_reply_info; |
2104 | err = parse_reply_info(msg, rinfo); | 2120 | err = parse_reply_info(msg, rinfo, session->s_con.peer_features); |
2105 | mutex_unlock(&mdsc->mutex); | 2121 | mutex_unlock(&mdsc->mutex); |
2106 | 2122 | ||
2107 | mutex_lock(&session->s_mutex); | 2123 | mutex_lock(&session->s_mutex); |
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index aabe563b54db..4e3a9cc0bba6 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h | |||
@@ -35,6 +35,7 @@ struct ceph_cap; | |||
35 | */ | 35 | */ |
36 | struct ceph_mds_reply_info_in { | 36 | struct ceph_mds_reply_info_in { |
37 | struct ceph_mds_reply_inode *in; | 37 | struct ceph_mds_reply_inode *in; |
38 | struct ceph_dir_layout dir_layout; | ||
38 | u32 symlink_len; | 39 | u32 symlink_len; |
39 | char *symlink; | 40 | char *symlink; |
40 | u32 xattr_len; | 41 | u32 xattr_len; |
@@ -165,7 +166,6 @@ struct ceph_mds_request { | |||
165 | struct ceph_mds_client *r_mdsc; | 166 | struct ceph_mds_client *r_mdsc; |
166 | 167 | ||
167 | int r_op; /* mds op code */ | 168 | int r_op; /* mds op code */ |
168 | int r_mds; | ||
169 | 169 | ||
170 | /* operation on what? */ | 170 | /* operation on what? */ |
171 | struct inode *r_inode; /* arg1 */ | 171 | struct inode *r_inode; /* arg1 */ |
diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 08b460ae0539..bf6f0f34082a 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c | |||
@@ -428,7 +428,8 @@ struct ceph_fs_client *create_fs_client(struct ceph_mount_options *fsopt, | |||
428 | goto fail; | 428 | goto fail; |
429 | } | 429 | } |
430 | fsc->client->extra_mon_dispatch = extra_mon_dispatch; | 430 | fsc->client->extra_mon_dispatch = extra_mon_dispatch; |
431 | fsc->client->supported_features |= CEPH_FEATURE_FLOCK; | 431 | fsc->client->supported_features |= CEPH_FEATURE_FLOCK | |
432 | CEPH_FEATURE_DIRLAYOUTHASH; | ||
432 | fsc->client->monc.want_mdsmap = 1; | 433 | fsc->client->monc.want_mdsmap = 1; |
433 | 434 | ||
434 | fsc->mount_options = fsopt; | 435 | fsc->mount_options = fsopt; |
@@ -443,13 +444,17 @@ struct ceph_fs_client *create_fs_client(struct ceph_mount_options *fsopt, | |||
443 | goto fail_client; | 444 | goto fail_client; |
444 | 445 | ||
445 | err = -ENOMEM; | 446 | err = -ENOMEM; |
446 | fsc->wb_wq = create_workqueue("ceph-writeback"); | 447 | /* |
448 | * The number of concurrent works can be high but they don't need | ||
449 | * to be processed in parallel, limit concurrency. | ||
450 | */ | ||
451 | fsc->wb_wq = alloc_workqueue("ceph-writeback", 0, 1); | ||
447 | if (fsc->wb_wq == NULL) | 452 | if (fsc->wb_wq == NULL) |
448 | goto fail_bdi; | 453 | goto fail_bdi; |
449 | fsc->pg_inv_wq = create_singlethread_workqueue("ceph-pg-invalid"); | 454 | fsc->pg_inv_wq = alloc_workqueue("ceph-pg-invalid", 0, 1); |
450 | if (fsc->pg_inv_wq == NULL) | 455 | if (fsc->pg_inv_wq == NULL) |
451 | goto fail_wb_wq; | 456 | goto fail_wb_wq; |
452 | fsc->trunc_wq = create_singlethread_workqueue("ceph-trunc"); | 457 | fsc->trunc_wq = alloc_workqueue("ceph-trunc", 0, 1); |
453 | if (fsc->trunc_wq == NULL) | 458 | if (fsc->trunc_wq == NULL) |
454 | goto fail_pg_inv_wq; | 459 | goto fail_pg_inv_wq; |
455 | 460 | ||
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 4553d8829edb..20b907d76ae2 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
@@ -239,6 +239,7 @@ struct ceph_inode_info { | |||
239 | unsigned i_ceph_flags; | 239 | unsigned i_ceph_flags; |
240 | unsigned long i_release_count; | 240 | unsigned long i_release_count; |
241 | 241 | ||
242 | struct ceph_dir_layout i_dir_layout; | ||
242 | struct ceph_file_layout i_layout; | 243 | struct ceph_file_layout i_layout; |
243 | char *i_symlink; | 244 | char *i_symlink; |
244 | 245 | ||
@@ -768,6 +769,7 @@ extern void ceph_dentry_lru_add(struct dentry *dn); | |||
768 | extern void ceph_dentry_lru_touch(struct dentry *dn); | 769 | extern void ceph_dentry_lru_touch(struct dentry *dn); |
769 | extern void ceph_dentry_lru_del(struct dentry *dn); | 770 | extern void ceph_dentry_lru_del(struct dentry *dn); |
770 | extern void ceph_invalidate_dentry_lease(struct dentry *dentry); | 771 | extern void ceph_invalidate_dentry_lease(struct dentry *dentry); |
772 | extern unsigned ceph_dentry_hash(struct dentry *dn); | ||
771 | 773 | ||
772 | /* | 774 | /* |
773 | * our d_ops vary depending on whether the inode is live, | 775 | * our d_ops vary depending on whether the inode is live, |
diff --git a/fs/char_dev.c b/fs/char_dev.c index e5b9df993b93..dca9e5e0f73b 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c | |||
@@ -59,7 +59,7 @@ static struct char_device_struct { | |||
59 | } *chrdevs[CHRDEV_MAJOR_HASH_SIZE]; | 59 | } *chrdevs[CHRDEV_MAJOR_HASH_SIZE]; |
60 | 60 | ||
61 | /* index in the above */ | 61 | /* index in the above */ |
62 | static inline int major_to_index(int major) | 62 | static inline int major_to_index(unsigned major) |
63 | { | 63 | { |
64 | return major % CHRDEV_MAJOR_HASH_SIZE; | 64 | return major % CHRDEV_MAJOR_HASH_SIZE; |
65 | } | 65 | } |
@@ -417,18 +417,6 @@ static int chrdev_open(struct inode *inode, struct file *filp) | |||
417 | return ret; | 417 | return ret; |
418 | } | 418 | } |
419 | 419 | ||
420 | int cdev_index(struct inode *inode) | ||
421 | { | ||
422 | int idx; | ||
423 | struct kobject *kobj; | ||
424 | |||
425 | kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx); | ||
426 | if (!kobj) | ||
427 | return -1; | ||
428 | kobject_put(kobj); | ||
429 | return idx; | ||
430 | } | ||
431 | |||
432 | void cd_forget(struct inode *inode) | 420 | void cd_forget(struct inode *inode) |
433 | { | 421 | { |
434 | spin_lock(&cdev_lock); | 422 | spin_lock(&cdev_lock); |
@@ -582,7 +570,6 @@ EXPORT_SYMBOL(cdev_init); | |||
582 | EXPORT_SYMBOL(cdev_alloc); | 570 | EXPORT_SYMBOL(cdev_alloc); |
583 | EXPORT_SYMBOL(cdev_del); | 571 | EXPORT_SYMBOL(cdev_del); |
584 | EXPORT_SYMBOL(cdev_add); | 572 | EXPORT_SYMBOL(cdev_add); |
585 | EXPORT_SYMBOL(cdev_index); | ||
586 | EXPORT_SYMBOL(__register_chrdev); | 573 | EXPORT_SYMBOL(__register_chrdev); |
587 | EXPORT_SYMBOL(__unregister_chrdev); | 574 | EXPORT_SYMBOL(__unregister_chrdev); |
588 | EXPORT_SYMBOL(directly_mappable_cdev_bdi); | 575 | EXPORT_SYMBOL(directly_mappable_cdev_bdi); |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 5e7075d5f139..d9f652a522a6 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -174,6 +174,12 @@ cifs_read_super(struct super_block *sb, void *data, | |||
174 | goto out_no_root; | 174 | goto out_no_root; |
175 | } | 175 | } |
176 | 176 | ||
177 | /* do that *after* d_alloc_root() - we want NULL ->d_op for root here */ | ||
178 | if (cifs_sb_master_tcon(cifs_sb)->nocase) | ||
179 | sb->s_d_op = &cifs_ci_dentry_ops; | ||
180 | else | ||
181 | sb->s_d_op = &cifs_dentry_ops; | ||
182 | |||
177 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 183 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
178 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { | 184 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { |
179 | cFYI(1, "export ops supported"); | 185 | cFYI(1, "export ops supported"); |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 2e773825835e..1e95dd635632 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -130,17 +130,6 @@ cifs_bp_rename_retry: | |||
130 | return full_path; | 130 | return full_path; |
131 | } | 131 | } |
132 | 132 | ||
133 | static void setup_cifs_dentry(struct cifsTconInfo *tcon, | ||
134 | struct dentry *direntry, | ||
135 | struct inode *newinode) | ||
136 | { | ||
137 | if (tcon->nocase) | ||
138 | d_set_d_op(direntry, &cifs_ci_dentry_ops); | ||
139 | else | ||
140 | d_set_d_op(direntry, &cifs_dentry_ops); | ||
141 | d_instantiate(direntry, newinode); | ||
142 | } | ||
143 | |||
144 | /* Inode operations in similar order to how they appear in Linux file fs.h */ | 133 | /* Inode operations in similar order to how they appear in Linux file fs.h */ |
145 | 134 | ||
146 | int | 135 | int |
@@ -327,7 +316,7 @@ cifs_create_get_file_info: | |||
327 | 316 | ||
328 | cifs_create_set_dentry: | 317 | cifs_create_set_dentry: |
329 | if (rc == 0) | 318 | if (rc == 0) |
330 | setup_cifs_dentry(tcon, direntry, newinode); | 319 | d_instantiate(direntry, newinode); |
331 | else | 320 | else |
332 | cFYI(1, "Create worked, get_inode_info failed rc = %d", rc); | 321 | cFYI(1, "Create worked, get_inode_info failed rc = %d", rc); |
333 | 322 | ||
@@ -418,10 +407,6 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, | |||
418 | 407 | ||
419 | rc = cifs_get_inode_info_unix(&newinode, full_path, | 408 | rc = cifs_get_inode_info_unix(&newinode, full_path, |
420 | inode->i_sb, xid); | 409 | inode->i_sb, xid); |
421 | if (pTcon->nocase) | ||
422 | d_set_d_op(direntry, &cifs_ci_dentry_ops); | ||
423 | else | ||
424 | d_set_d_op(direntry, &cifs_dentry_ops); | ||
425 | 410 | ||
426 | if (rc == 0) | 411 | if (rc == 0) |
427 | d_instantiate(direntry, newinode); | 412 | d_instantiate(direntry, newinode); |
@@ -601,10 +586,6 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
601 | parent_dir_inode->i_sb, xid, NULL); | 586 | parent_dir_inode->i_sb, xid, NULL); |
602 | 587 | ||
603 | if ((rc == 0) && (newInode != NULL)) { | 588 | if ((rc == 0) && (newInode != NULL)) { |
604 | if (pTcon->nocase) | ||
605 | d_set_d_op(direntry, &cifs_ci_dentry_ops); | ||
606 | else | ||
607 | d_set_d_op(direntry, &cifs_dentry_ops); | ||
608 | d_add(direntry, newInode); | 589 | d_add(direntry, newInode); |
609 | if (posix_open) { | 590 | if (posix_open) { |
610 | filp = lookup_instantiate_filp(nd, direntry, | 591 | filp = lookup_instantiate_filp(nd, direntry, |
@@ -631,10 +612,6 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
631 | } else if (rc == -ENOENT) { | 612 | } else if (rc == -ENOENT) { |
632 | rc = 0; | 613 | rc = 0; |
633 | direntry->d_time = jiffies; | 614 | direntry->d_time = jiffies; |
634 | if (pTcon->nocase) | ||
635 | d_set_d_op(direntry, &cifs_ci_dentry_ops); | ||
636 | else | ||
637 | d_set_d_op(direntry, &cifs_dentry_ops); | ||
638 | d_add(direntry, NULL); | 615 | d_add(direntry, NULL); |
639 | /* if it was once a directory (but how can we tell?) we could do | 616 | /* if it was once a directory (but how can we tell?) we could do |
640 | shrink_dcache_parent(direntry); */ | 617 | shrink_dcache_parent(direntry); */ |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 0c7e36910e31..b06b60620240 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -1324,10 +1324,6 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) | |||
1324 | /*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need | 1324 | /*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need |
1325 | to set uid/gid */ | 1325 | to set uid/gid */ |
1326 | inc_nlink(inode); | 1326 | inc_nlink(inode); |
1327 | if (pTcon->nocase) | ||
1328 | d_set_d_op(direntry, &cifs_ci_dentry_ops); | ||
1329 | else | ||
1330 | d_set_d_op(direntry, &cifs_dentry_ops); | ||
1331 | 1327 | ||
1332 | cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb); | 1328 | cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb); |
1333 | cifs_fill_uniqueid(inode->i_sb, &fattr); | 1329 | cifs_fill_uniqueid(inode->i_sb, &fattr); |
@@ -1368,10 +1364,6 @@ mkdir_get_info: | |||
1368 | rc = cifs_get_inode_info(&newinode, full_path, NULL, | 1364 | rc = cifs_get_inode_info(&newinode, full_path, NULL, |
1369 | inode->i_sb, xid, NULL); | 1365 | inode->i_sb, xid, NULL); |
1370 | 1366 | ||
1371 | if (pTcon->nocase) | ||
1372 | d_set_d_op(direntry, &cifs_ci_dentry_ops); | ||
1373 | else | ||
1374 | d_set_d_op(direntry, &cifs_dentry_ops); | ||
1375 | d_instantiate(direntry, newinode); | 1367 | d_instantiate(direntry, newinode); |
1376 | /* setting nlink not necessary except in cases where we | 1368 | /* setting nlink not necessary except in cases where we |
1377 | * failed to get it from the server or was set bogus */ | 1369 | * failed to get it from the server or was set bogus */ |
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index fe2f6a93c49e..306769de2fb5 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
@@ -524,10 +524,6 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname) | |||
524 | cFYI(1, "Create symlink ok, getinodeinfo fail rc = %d", | 524 | cFYI(1, "Create symlink ok, getinodeinfo fail rc = %d", |
525 | rc); | 525 | rc); |
526 | } else { | 526 | } else { |
527 | if (pTcon->nocase) | ||
528 | d_set_d_op(direntry, &cifs_ci_dentry_ops); | ||
529 | else | ||
530 | d_set_d_op(direntry, &cifs_dentry_ops); | ||
531 | d_instantiate(direntry, newinode); | 527 | d_instantiate(direntry, newinode); |
532 | } | 528 | } |
533 | } | 529 | } |
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 76b1b37c9e6b..7f25cc3d2256 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
@@ -102,11 +102,6 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name, | |||
102 | return NULL; | 102 | return NULL; |
103 | } | 103 | } |
104 | 104 | ||
105 | if (cifs_sb_master_tcon(CIFS_SB(sb))->nocase) | ||
106 | d_set_d_op(dentry, &cifs_ci_dentry_ops); | ||
107 | else | ||
108 | d_set_d_op(dentry, &cifs_dentry_ops); | ||
109 | |||
110 | alias = d_materialise_unique(dentry, inode); | 105 | alias = d_materialise_unique(dentry, inode); |
111 | if (alias != NULL) { | 106 | if (alias != NULL) { |
112 | dput(dentry); | 107 | dput(dentry); |
diff --git a/fs/coda/cache.c b/fs/coda/cache.c index 5525e1c660fd..690157876184 100644 --- a/fs/coda/cache.c +++ b/fs/coda/cache.c | |||
@@ -20,10 +20,9 @@ | |||
20 | #include <linux/spinlock.h> | 20 | #include <linux/spinlock.h> |
21 | 21 | ||
22 | #include <linux/coda.h> | 22 | #include <linux/coda.h> |
23 | #include <linux/coda_linux.h> | ||
24 | #include <linux/coda_psdev.h> | 23 | #include <linux/coda_psdev.h> |
25 | #include <linux/coda_fs_i.h> | 24 | #include "coda_linux.h" |
26 | #include <linux/coda_cache.h> | 25 | #include "coda_cache.h" |
27 | 26 | ||
28 | static atomic_t permission_epoch = ATOMIC_INIT(0); | 27 | static atomic_t permission_epoch = ATOMIC_INIT(0); |
29 | 28 | ||
diff --git a/fs/coda/cnode.c b/fs/coda/cnode.c index 602240569c89..6475877b0763 100644 --- a/fs/coda/cnode.c +++ b/fs/coda/cnode.c | |||
@@ -7,9 +7,8 @@ | |||
7 | #include <linux/time.h> | 7 | #include <linux/time.h> |
8 | 8 | ||
9 | #include <linux/coda.h> | 9 | #include <linux/coda.h> |
10 | #include <linux/coda_linux.h> | ||
11 | #include <linux/coda_fs_i.h> | ||
12 | #include <linux/coda_psdev.h> | 10 | #include <linux/coda_psdev.h> |
11 | #include "coda_linux.h" | ||
13 | 12 | ||
14 | static inline int coda_fideq(struct CodaFid *fid1, struct CodaFid *fid2) | 13 | static inline int coda_fideq(struct CodaFid *fid1, struct CodaFid *fid2) |
15 | { | 14 | { |
diff --git a/fs/coda/coda_cache.h b/fs/coda/coda_cache.h new file mode 100644 index 000000000000..c910b5eb1ceb --- /dev/null +++ b/fs/coda/coda_cache.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* Coda filesystem -- Linux Minicache | ||
2 | * | ||
3 | * Copyright (C) 1989 - 1997 Carnegie Mellon University | ||
4 | * | ||
5 | * Carnegie Mellon University encourages users of this software to | ||
6 | * contribute improvements to the Coda project. Contact Peter Braam | ||
7 | * <coda@cs.cmu.edu> | ||
8 | */ | ||
9 | |||
10 | #ifndef _CFSNC_HEADER_ | ||
11 | #define _CFSNC_HEADER_ | ||
12 | |||
13 | /* credential cache */ | ||
14 | void coda_cache_enter(struct inode *inode, int mask); | ||
15 | void coda_cache_clear_inode(struct inode *); | ||
16 | void coda_cache_clear_all(struct super_block *sb); | ||
17 | int coda_cache_check(struct inode *inode, int mask); | ||
18 | |||
19 | /* for downcalls and attributes and lookups */ | ||
20 | void coda_flag_inode_children(struct inode *inode, int flag); | ||
21 | |||
22 | #endif /* _CFSNC_HEADER_ */ | ||
diff --git a/fs/coda/coda_fs_i.h b/fs/coda/coda_fs_i.h new file mode 100644 index 000000000000..e35071b1de0e --- /dev/null +++ b/fs/coda/coda_fs_i.h | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | * coda_fs_i.h | ||
3 | * | ||
4 | * Copyright (C) 1998 Carnegie Mellon University | ||
5 | * | ||
6 | */ | ||
7 | |||
8 | #ifndef _LINUX_CODA_FS_I | ||
9 | #define _LINUX_CODA_FS_I | ||
10 | |||
11 | #include <linux/types.h> | ||
12 | #include <linux/list.h> | ||
13 | #include <linux/spinlock.h> | ||
14 | #include <linux/coda.h> | ||
15 | |||
16 | /* | ||
17 | * coda fs inode data | ||
18 | * c_lock protects accesses to c_flags, c_mapcount, c_cached_epoch, c_uid and | ||
19 | * c_cached_perm. | ||
20 | * vfs_inode is set only when the inode is created and never changes. | ||
21 | * c_fid is set when the inode is created and should be considered immutable. | ||
22 | */ | ||
23 | struct coda_inode_info { | ||
24 | struct CodaFid c_fid; /* Coda identifier */ | ||
25 | u_short c_flags; /* flags (see below) */ | ||
26 | unsigned int c_mapcount; /* nr of times this inode is mapped */ | ||
27 | unsigned int c_cached_epoch; /* epoch for cached permissions */ | ||
28 | vuid_t c_uid; /* fsuid for cached permissions */ | ||
29 | unsigned int c_cached_perm; /* cached access permissions */ | ||
30 | spinlock_t c_lock; | ||
31 | struct inode vfs_inode; | ||
32 | }; | ||
33 | |||
34 | /* | ||
35 | * coda fs file private data | ||
36 | */ | ||
37 | #define CODA_MAGIC 0xC0DAC0DA | ||
38 | struct coda_file_info { | ||
39 | int cfi_magic; /* magic number */ | ||
40 | struct file *cfi_container; /* container file for this cnode */ | ||
41 | unsigned int cfi_mapcount; /* nr of times this file is mapped */ | ||
42 | }; | ||
43 | |||
44 | #define CODA_FTOC(file) ((struct coda_file_info *)((file)->private_data)) | ||
45 | |||
46 | /* flags */ | ||
47 | #define C_VATTR 0x1 /* Validity of vattr in inode */ | ||
48 | #define C_FLUSH 0x2 /* used after a flush */ | ||
49 | #define C_DYING 0x4 /* from venus (which died) */ | ||
50 | #define C_PURGE 0x8 | ||
51 | |||
52 | int coda_cnode_make(struct inode **, struct CodaFid *, struct super_block *); | ||
53 | struct inode *coda_iget(struct super_block *sb, struct CodaFid *fid, struct coda_vattr *attr); | ||
54 | int coda_cnode_makectl(struct inode **inode, struct super_block *sb); | ||
55 | struct inode *coda_fid_to_inode(struct CodaFid *fid, struct super_block *sb); | ||
56 | void coda_replace_fid(struct inode *, struct CodaFid *, struct CodaFid *); | ||
57 | |||
58 | #endif | ||
diff --git a/fs/coda/coda_linux.c b/fs/coda/coda_linux.c index bf4a3fd3c8e3..2bdbcc11b373 100644 --- a/fs/coda/coda_linux.c +++ b/fs/coda/coda_linux.c | |||
@@ -17,9 +17,8 @@ | |||
17 | #include <linux/string.h> | 17 | #include <linux/string.h> |
18 | 18 | ||
19 | #include <linux/coda.h> | 19 | #include <linux/coda.h> |
20 | #include <linux/coda_linux.h> | ||
21 | #include <linux/coda_psdev.h> | 20 | #include <linux/coda_psdev.h> |
22 | #include <linux/coda_fs_i.h> | 21 | #include "coda_linux.h" |
23 | 22 | ||
24 | /* initialize the debugging variables */ | 23 | /* initialize the debugging variables */ |
25 | int coda_fake_statfs; | 24 | int coda_fake_statfs; |
diff --git a/fs/coda/coda_linux.h b/fs/coda/coda_linux.h new file mode 100644 index 000000000000..9b0c5323890b --- /dev/null +++ b/fs/coda/coda_linux.h | |||
@@ -0,0 +1,101 @@ | |||
1 | /* | ||
2 | * Coda File System, Linux Kernel module | ||
3 | * | ||
4 | * Original version, adapted from cfs_mach.c, (C) Carnegie Mellon University | ||
5 | * Linux modifications (C) 1996, Peter J. Braam | ||
6 | * Rewritten for Linux 2.1 (C) 1997 Carnegie Mellon University | ||
7 | * | ||
8 | * Carnegie Mellon University encourages users of this software to | ||
9 | * contribute improvements to the Coda project. | ||
10 | */ | ||
11 | |||
12 | #ifndef _LINUX_CODA_FS | ||
13 | #define _LINUX_CODA_FS | ||
14 | |||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/param.h> | ||
17 | #include <linux/mm.h> | ||
18 | #include <linux/vmalloc.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/wait.h> | ||
21 | #include <linux/types.h> | ||
22 | #include <linux/fs.h> | ||
23 | #include "coda_fs_i.h" | ||
24 | |||
25 | /* operations */ | ||
26 | extern const struct inode_operations coda_dir_inode_operations; | ||
27 | extern const struct inode_operations coda_file_inode_operations; | ||
28 | extern const struct inode_operations coda_ioctl_inode_operations; | ||
29 | |||
30 | extern const struct dentry_operations coda_dentry_operations; | ||
31 | |||
32 | extern const struct address_space_operations coda_file_aops; | ||
33 | extern const struct address_space_operations coda_symlink_aops; | ||
34 | |||
35 | extern const struct file_operations coda_dir_operations; | ||
36 | extern const struct file_operations coda_file_operations; | ||
37 | extern const struct file_operations coda_ioctl_operations; | ||
38 | |||
39 | /* operations shared over more than one file */ | ||
40 | int coda_open(struct inode *i, struct file *f); | ||
41 | int coda_release(struct inode *i, struct file *f); | ||
42 | int coda_permission(struct inode *inode, int mask, unsigned int flags); | ||
43 | int coda_revalidate_inode(struct dentry *); | ||
44 | int coda_getattr(struct vfsmount *, struct dentry *, struct kstat *); | ||
45 | int coda_setattr(struct dentry *, struct iattr *); | ||
46 | |||
47 | /* this file: heloers */ | ||
48 | char *coda_f2s(struct CodaFid *f); | ||
49 | int coda_isroot(struct inode *i); | ||
50 | int coda_iscontrol(const char *name, size_t length); | ||
51 | |||
52 | void coda_vattr_to_iattr(struct inode *, struct coda_vattr *); | ||
53 | void coda_iattr_to_vattr(struct iattr *, struct coda_vattr *); | ||
54 | unsigned short coda_flags_to_cflags(unsigned short); | ||
55 | |||
56 | /* sysctl.h */ | ||
57 | void coda_sysctl_init(void); | ||
58 | void coda_sysctl_clean(void); | ||
59 | |||
60 | #define CODA_ALLOC(ptr, cast, size) do { \ | ||
61 | if (size < PAGE_SIZE) \ | ||
62 | ptr = kmalloc((unsigned long) size, GFP_KERNEL); \ | ||
63 | else \ | ||
64 | ptr = (cast)vmalloc((unsigned long) size); \ | ||
65 | if (!ptr) \ | ||
66 | printk("kernel malloc returns 0 at %s:%d\n", __FILE__, __LINE__); \ | ||
67 | else memset( ptr, 0, size ); \ | ||
68 | } while (0) | ||
69 | |||
70 | |||
71 | #define CODA_FREE(ptr,size) \ | ||
72 | do { if (size < PAGE_SIZE) kfree((ptr)); else vfree((ptr)); } while (0) | ||
73 | |||
74 | /* inode to cnode access functions */ | ||
75 | |||
76 | static inline struct coda_inode_info *ITOC(struct inode *inode) | ||
77 | { | ||
78 | return list_entry(inode, struct coda_inode_info, vfs_inode); | ||
79 | } | ||
80 | |||
81 | static __inline__ struct CodaFid *coda_i2f(struct inode *inode) | ||
82 | { | ||
83 | return &(ITOC(inode)->c_fid); | ||
84 | } | ||
85 | |||
86 | static __inline__ char *coda_i2s(struct inode *inode) | ||
87 | { | ||
88 | return coda_f2s(&(ITOC(inode)->c_fid)); | ||
89 | } | ||
90 | |||
91 | /* this will not zap the inode away */ | ||
92 | static __inline__ void coda_flag_inode(struct inode *inode, int flag) | ||
93 | { | ||
94 | struct coda_inode_info *cii = ITOC(inode); | ||
95 | |||
96 | spin_lock(&cii->c_lock); | ||
97 | cii->c_flags |= flag; | ||
98 | spin_unlock(&cii->c_lock); | ||
99 | } | ||
100 | |||
101 | #endif | ||
diff --git a/fs/coda/dir.c b/fs/coda/dir.c index 29badd91360f..2b8dae4d121e 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c | |||
@@ -23,10 +23,9 @@ | |||
23 | #include <asm/uaccess.h> | 23 | #include <asm/uaccess.h> |
24 | 24 | ||
25 | #include <linux/coda.h> | 25 | #include <linux/coda.h> |
26 | #include <linux/coda_linux.h> | ||
27 | #include <linux/coda_psdev.h> | 26 | #include <linux/coda_psdev.h> |
28 | #include <linux/coda_fs_i.h> | 27 | #include "coda_linux.h" |
29 | #include <linux/coda_cache.h> | 28 | #include "coda_cache.h" |
30 | 29 | ||
31 | #include "coda_int.h" | 30 | #include "coda_int.h" |
32 | 31 | ||
@@ -61,7 +60,7 @@ static int coda_return_EIO(void) | |||
61 | } | 60 | } |
62 | #define CODA_EIO_ERROR ((void *) (coda_return_EIO)) | 61 | #define CODA_EIO_ERROR ((void *) (coda_return_EIO)) |
63 | 62 | ||
64 | static const struct dentry_operations coda_dentry_operations = | 63 | const struct dentry_operations coda_dentry_operations = |
65 | { | 64 | { |
66 | .d_revalidate = coda_dentry_revalidate, | 65 | .d_revalidate = coda_dentry_revalidate, |
67 | .d_delete = coda_dentry_delete, | 66 | .d_delete = coda_dentry_delete, |
@@ -126,8 +125,6 @@ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, struc | |||
126 | return ERR_PTR(error); | 125 | return ERR_PTR(error); |
127 | 126 | ||
128 | exit: | 127 | exit: |
129 | d_set_d_op(entry, &coda_dentry_operations); | ||
130 | |||
131 | if (inode && (type & CODA_NOCACHE)) | 128 | if (inode && (type & CODA_NOCACHE)) |
132 | coda_flag_inode(inode, C_VATTR | C_PURGE); | 129 | coda_flag_inode(inode, C_VATTR | C_PURGE); |
133 | 130 | ||
diff --git a/fs/coda/file.c b/fs/coda/file.c index c8b50ba4366a..0433057be330 100644 --- a/fs/coda/file.c +++ b/fs/coda/file.c | |||
@@ -21,10 +21,9 @@ | |||
21 | #include <asm/uaccess.h> | 21 | #include <asm/uaccess.h> |
22 | 22 | ||
23 | #include <linux/coda.h> | 23 | #include <linux/coda.h> |
24 | #include <linux/coda_linux.h> | ||
25 | #include <linux/coda_fs_i.h> | ||
26 | #include <linux/coda_psdev.h> | 24 | #include <linux/coda_psdev.h> |
27 | 25 | ||
26 | #include "coda_linux.h" | ||
28 | #include "coda_int.h" | 27 | #include "coda_int.h" |
29 | 28 | ||
30 | static ssize_t | 29 | static ssize_t |
diff --git a/fs/coda/inode.c b/fs/coda/inode.c index 50dc7d189f56..871b27715465 100644 --- a/fs/coda/inode.c +++ b/fs/coda/inode.c | |||
@@ -28,10 +28,9 @@ | |||
28 | #include <linux/vmalloc.h> | 28 | #include <linux/vmalloc.h> |
29 | 29 | ||
30 | #include <linux/coda.h> | 30 | #include <linux/coda.h> |
31 | #include <linux/coda_linux.h> | ||
32 | #include <linux/coda_psdev.h> | 31 | #include <linux/coda_psdev.h> |
33 | #include <linux/coda_fs_i.h> | 32 | #include "coda_linux.h" |
34 | #include <linux/coda_cache.h> | 33 | #include "coda_cache.h" |
35 | 34 | ||
36 | #include "coda_int.h" | 35 | #include "coda_int.h" |
37 | 36 | ||
@@ -45,7 +44,7 @@ static struct kmem_cache * coda_inode_cachep; | |||
45 | static struct inode *coda_alloc_inode(struct super_block *sb) | 44 | static struct inode *coda_alloc_inode(struct super_block *sb) |
46 | { | 45 | { |
47 | struct coda_inode_info *ei; | 46 | struct coda_inode_info *ei; |
48 | ei = (struct coda_inode_info *)kmem_cache_alloc(coda_inode_cachep, GFP_KERNEL); | 47 | ei = kmem_cache_alloc(coda_inode_cachep, GFP_KERNEL); |
49 | if (!ei) | 48 | if (!ei) |
50 | return NULL; | 49 | return NULL; |
51 | memset(&ei->c_fid, 0, sizeof(struct CodaFid)); | 50 | memset(&ei->c_fid, 0, sizeof(struct CodaFid)); |
@@ -193,6 +192,7 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent) | |||
193 | sb->s_blocksize_bits = 12; | 192 | sb->s_blocksize_bits = 12; |
194 | sb->s_magic = CODA_SUPER_MAGIC; | 193 | sb->s_magic = CODA_SUPER_MAGIC; |
195 | sb->s_op = &coda_super_operations; | 194 | sb->s_op = &coda_super_operations; |
195 | sb->s_d_op = &coda_dentry_operations; | ||
196 | sb->s_bdi = &vc->bdi; | 196 | sb->s_bdi = &vc->bdi; |
197 | 197 | ||
198 | /* get root fid from Venus: this needs the root inode */ | 198 | /* get root fid from Venus: this needs the root inode */ |
diff --git a/fs/coda/pioctl.c b/fs/coda/pioctl.c index 741f0bd03918..6cbb3afb36dc 100644 --- a/fs/coda/pioctl.c +++ b/fs/coda/pioctl.c | |||
@@ -19,10 +19,10 @@ | |||
19 | #include <asm/uaccess.h> | 19 | #include <asm/uaccess.h> |
20 | 20 | ||
21 | #include <linux/coda.h> | 21 | #include <linux/coda.h> |
22 | #include <linux/coda_linux.h> | ||
23 | #include <linux/coda_fs_i.h> | ||
24 | #include <linux/coda_psdev.h> | 22 | #include <linux/coda_psdev.h> |
25 | 23 | ||
24 | #include "coda_linux.h" | ||
25 | |||
26 | /* pioctl ops */ | 26 | /* pioctl ops */ |
27 | static int coda_ioctl_permission(struct inode *inode, int mask, unsigned int flags); | 27 | static int coda_ioctl_permission(struct inode *inode, int mask, unsigned int flags); |
28 | static long coda_pioctl(struct file *filp, unsigned int cmd, | 28 | static long coda_pioctl(struct file *filp, unsigned int cmd, |
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c index 62647a8595e4..8f616e0e252c 100644 --- a/fs/coda/psdev.c +++ b/fs/coda/psdev.c | |||
@@ -43,10 +43,10 @@ | |||
43 | #include <asm/uaccess.h> | 43 | #include <asm/uaccess.h> |
44 | 44 | ||
45 | #include <linux/coda.h> | 45 | #include <linux/coda.h> |
46 | #include <linux/coda_linux.h> | ||
47 | #include <linux/coda_fs_i.h> | ||
48 | #include <linux/coda_psdev.h> | 46 | #include <linux/coda_psdev.h> |
49 | 47 | ||
48 | #include "coda_linux.h" | ||
49 | |||
50 | #include "coda_int.h" | 50 | #include "coda_int.h" |
51 | 51 | ||
52 | /* statistics */ | 52 | /* statistics */ |
diff --git a/fs/coda/symlink.c b/fs/coda/symlink.c index af78f007a2b0..ab94ef63caef 100644 --- a/fs/coda/symlink.c +++ b/fs/coda/symlink.c | |||
@@ -16,9 +16,9 @@ | |||
16 | #include <linux/pagemap.h> | 16 | #include <linux/pagemap.h> |
17 | 17 | ||
18 | #include <linux/coda.h> | 18 | #include <linux/coda.h> |
19 | #include <linux/coda_linux.h> | ||
20 | #include <linux/coda_psdev.h> | 19 | #include <linux/coda_psdev.h> |
21 | #include <linux/coda_fs_i.h> | 20 | |
21 | #include "coda_linux.h" | ||
22 | 22 | ||
23 | static int coda_symlink_filler(struct file *file, struct page *page) | 23 | static int coda_symlink_filler(struct file *file, struct page *page) |
24 | { | 24 | { |
diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c index c3563cab9758..9727e0c52579 100644 --- a/fs/coda/upcall.c +++ b/fs/coda/upcall.c | |||
@@ -33,10 +33,9 @@ | |||
33 | #include <linux/vfs.h> | 33 | #include <linux/vfs.h> |
34 | 34 | ||
35 | #include <linux/coda.h> | 35 | #include <linux/coda.h> |
36 | #include <linux/coda_linux.h> | ||
37 | #include <linux/coda_psdev.h> | 36 | #include <linux/coda_psdev.h> |
38 | #include <linux/coda_fs_i.h> | 37 | #include "coda_linux.h" |
39 | #include <linux/coda_cache.h> | 38 | #include "coda_cache.h" |
40 | 39 | ||
41 | #include "coda_int.h" | 40 | #include "coda_int.h" |
42 | 41 | ||
diff --git a/fs/configfs/configfs_internal.h b/fs/configfs/configfs_internal.h index 026cf68553a4..82bda8fdfc1c 100644 --- a/fs/configfs/configfs_internal.h +++ b/fs/configfs/configfs_internal.h | |||
@@ -90,6 +90,7 @@ extern const struct file_operations configfs_file_operations; | |||
90 | extern const struct file_operations bin_fops; | 90 | extern const struct file_operations bin_fops; |
91 | extern const struct inode_operations configfs_dir_inode_operations; | 91 | extern const struct inode_operations configfs_dir_inode_operations; |
92 | extern const struct inode_operations configfs_symlink_inode_operations; | 92 | extern const struct inode_operations configfs_symlink_inode_operations; |
93 | extern const struct dentry_operations configfs_dentry_ops; | ||
93 | 94 | ||
94 | extern int configfs_symlink(struct inode *dir, struct dentry *dentry, | 95 | extern int configfs_symlink(struct inode *dir, struct dentry *dentry, |
95 | const char *symname); | 96 | const char *symname); |
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 36637a8c1ed3..90ff3cb10de3 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c | |||
@@ -72,7 +72,7 @@ static int configfs_d_delete(const struct dentry *dentry) | |||
72 | return 1; | 72 | return 1; |
73 | } | 73 | } |
74 | 74 | ||
75 | static const struct dentry_operations configfs_dentry_ops = { | 75 | const struct dentry_operations configfs_dentry_ops = { |
76 | .d_iput = configfs_d_iput, | 76 | .d_iput = configfs_d_iput, |
77 | /* simple_delete_dentry() isn't exported */ | 77 | /* simple_delete_dentry() isn't exported */ |
78 | .d_delete = configfs_d_delete, | 78 | .d_delete = configfs_d_delete, |
@@ -442,7 +442,6 @@ static int configfs_attach_attr(struct configfs_dirent * sd, struct dentry * den | |||
442 | return error; | 442 | return error; |
443 | } | 443 | } |
444 | 444 | ||
445 | d_set_d_op(dentry, &configfs_dentry_ops); | ||
446 | d_rehash(dentry); | 445 | d_rehash(dentry); |
447 | 446 | ||
448 | return 0; | 447 | return 0; |
@@ -489,7 +488,6 @@ static struct dentry * configfs_lookup(struct inode *dir, | |||
489 | */ | 488 | */ |
490 | if (dentry->d_name.len > NAME_MAX) | 489 | if (dentry->d_name.len > NAME_MAX) |
491 | return ERR_PTR(-ENAMETOOLONG); | 490 | return ERR_PTR(-ENAMETOOLONG); |
492 | d_set_d_op(dentry, &configfs_dentry_ops); | ||
493 | d_add(dentry, NULL); | 491 | d_add(dentry, NULL); |
494 | return NULL; | 492 | return NULL; |
495 | } | 493 | } |
@@ -683,7 +681,6 @@ static int create_default_group(struct config_group *parent_group, | |||
683 | ret = -ENOMEM; | 681 | ret = -ENOMEM; |
684 | child = d_alloc(parent, &name); | 682 | child = d_alloc(parent, &name); |
685 | if (child) { | 683 | if (child) { |
686 | d_set_d_op(child, &configfs_dentry_ops); | ||
687 | d_add(child, NULL); | 684 | d_add(child, NULL); |
688 | 685 | ||
689 | ret = configfs_attach_group(&parent_group->cg_item, | 686 | ret = configfs_attach_group(&parent_group->cg_item, |
@@ -1681,7 +1678,6 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys) | |||
1681 | err = -ENOMEM; | 1678 | err = -ENOMEM; |
1682 | dentry = d_alloc(configfs_sb->s_root, &name); | 1679 | dentry = d_alloc(configfs_sb->s_root, &name); |
1683 | if (dentry) { | 1680 | if (dentry) { |
1684 | d_set_d_op(dentry, &configfs_dentry_ops); | ||
1685 | d_add(dentry, NULL); | 1681 | d_add(dentry, NULL); |
1686 | 1682 | ||
1687 | err = configfs_attach_group(sd->s_element, &group->cg_item, | 1683 | err = configfs_attach_group(sd->s_element, &group->cg_item, |
diff --git a/fs/configfs/mount.c b/fs/configfs/mount.c index 7d3607febe1c..ecc62178beda 100644 --- a/fs/configfs/mount.c +++ b/fs/configfs/mount.c | |||
@@ -101,6 +101,7 @@ static int configfs_fill_super(struct super_block *sb, void *data, int silent) | |||
101 | configfs_root_group.cg_item.ci_dentry = root; | 101 | configfs_root_group.cg_item.ci_dentry = root; |
102 | root->d_fsdata = &configfs_root; | 102 | root->d_fsdata = &configfs_root; |
103 | sb->s_root = root; | 103 | sb->s_root = root; |
104 | sb->s_d_op = &configfs_dentry_ops; /* the rest get that */ | ||
104 | return 0; | 105 | return 0; |
105 | } | 106 | } |
106 | 107 | ||
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index 32fd5fe9ca0e..e141939080f0 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c | |||
@@ -34,57 +34,81 @@ static const struct address_space_operations cramfs_aops; | |||
34 | static DEFINE_MUTEX(read_mutex); | 34 | static DEFINE_MUTEX(read_mutex); |
35 | 35 | ||
36 | 36 | ||
37 | /* These two macros may change in future, to provide better st_ino | 37 | /* These macros may change in future, to provide better st_ino semantics. */ |
38 | semantics. */ | ||
39 | #define CRAMINO(x) (((x)->offset && (x)->size)?(x)->offset<<2:1) | ||
40 | #define OFFSET(x) ((x)->i_ino) | 38 | #define OFFSET(x) ((x)->i_ino) |
41 | 39 | ||
42 | static void setup_inode(struct inode *inode, struct cramfs_inode * cramfs_inode) | 40 | static unsigned long cramino(struct cramfs_inode *cino, unsigned int offset) |
43 | { | 41 | { |
42 | if (!cino->offset) | ||
43 | return offset + 1; | ||
44 | if (!cino->size) | ||
45 | return offset + 1; | ||
46 | |||
47 | /* | ||
48 | * The file mode test fixes buggy mkcramfs implementations where | ||
49 | * cramfs_inode->offset is set to a non zero value for entries | ||
50 | * which did not contain data, like devices node and fifos. | ||
51 | */ | ||
52 | switch (cino->mode & S_IFMT) { | ||
53 | case S_IFREG: | ||
54 | case S_IFDIR: | ||
55 | case S_IFLNK: | ||
56 | return cino->offset << 2; | ||
57 | default: | ||
58 | break; | ||
59 | } | ||
60 | return offset + 1; | ||
61 | } | ||
62 | |||
63 | static struct inode *get_cramfs_inode(struct super_block *sb, | ||
64 | struct cramfs_inode *cramfs_inode, unsigned int offset) | ||
65 | { | ||
66 | struct inode *inode; | ||
44 | static struct timespec zerotime; | 67 | static struct timespec zerotime; |
68 | |||
69 | inode = iget_locked(sb, cramino(cramfs_inode, offset)); | ||
70 | if (!inode) | ||
71 | return ERR_PTR(-ENOMEM); | ||
72 | if (!(inode->i_state & I_NEW)) | ||
73 | return inode; | ||
74 | |||
75 | switch (cramfs_inode->mode & S_IFMT) { | ||
76 | case S_IFREG: | ||
77 | inode->i_fop = &generic_ro_fops; | ||
78 | inode->i_data.a_ops = &cramfs_aops; | ||
79 | break; | ||
80 | case S_IFDIR: | ||
81 | inode->i_op = &cramfs_dir_inode_operations; | ||
82 | inode->i_fop = &cramfs_directory_operations; | ||
83 | break; | ||
84 | case S_IFLNK: | ||
85 | inode->i_op = &page_symlink_inode_operations; | ||
86 | inode->i_data.a_ops = &cramfs_aops; | ||
87 | break; | ||
88 | default: | ||
89 | init_special_inode(inode, cramfs_inode->mode, | ||
90 | old_decode_dev(cramfs_inode->size)); | ||
91 | } | ||
92 | |||
45 | inode->i_mode = cramfs_inode->mode; | 93 | inode->i_mode = cramfs_inode->mode; |
46 | inode->i_uid = cramfs_inode->uid; | 94 | inode->i_uid = cramfs_inode->uid; |
47 | inode->i_size = cramfs_inode->size; | ||
48 | inode->i_blocks = (cramfs_inode->size - 1) / 512 + 1; | ||
49 | inode->i_gid = cramfs_inode->gid; | 95 | inode->i_gid = cramfs_inode->gid; |
96 | |||
97 | /* if the lower 2 bits are zero, the inode contains data */ | ||
98 | if (!(inode->i_ino & 3)) { | ||
99 | inode->i_size = cramfs_inode->size; | ||
100 | inode->i_blocks = (cramfs_inode->size - 1) / 512 + 1; | ||
101 | } | ||
102 | |||
50 | /* Struct copy intentional */ | 103 | /* Struct copy intentional */ |
51 | inode->i_mtime = inode->i_atime = inode->i_ctime = zerotime; | 104 | inode->i_mtime = inode->i_atime = inode->i_ctime = zerotime; |
52 | /* inode->i_nlink is left 1 - arguably wrong for directories, | 105 | /* inode->i_nlink is left 1 - arguably wrong for directories, |
53 | but it's the best we can do without reading the directory | 106 | but it's the best we can do without reading the directory |
54 | contents. 1 yields the right result in GNU find, even | 107 | contents. 1 yields the right result in GNU find, even |
55 | without -noleaf option. */ | 108 | without -noleaf option. */ |
56 | if (S_ISREG(inode->i_mode)) { | ||
57 | inode->i_fop = &generic_ro_fops; | ||
58 | inode->i_data.a_ops = &cramfs_aops; | ||
59 | } else if (S_ISDIR(inode->i_mode)) { | ||
60 | inode->i_op = &cramfs_dir_inode_operations; | ||
61 | inode->i_fop = &cramfs_directory_operations; | ||
62 | } else if (S_ISLNK(inode->i_mode)) { | ||
63 | inode->i_op = &page_symlink_inode_operations; | ||
64 | inode->i_data.a_ops = &cramfs_aops; | ||
65 | } else { | ||
66 | init_special_inode(inode, inode->i_mode, | ||
67 | old_decode_dev(cramfs_inode->size)); | ||
68 | } | ||
69 | } | ||
70 | 109 | ||
71 | static struct inode *get_cramfs_inode(struct super_block *sb, | 110 | unlock_new_inode(inode); |
72 | struct cramfs_inode * cramfs_inode) | 111 | |
73 | { | ||
74 | struct inode *inode; | ||
75 | if (CRAMINO(cramfs_inode) == 1) { | ||
76 | inode = new_inode(sb); | ||
77 | if (inode) { | ||
78 | inode->i_ino = 1; | ||
79 | setup_inode(inode, cramfs_inode); | ||
80 | } | ||
81 | } else { | ||
82 | inode = iget_locked(sb, CRAMINO(cramfs_inode)); | ||
83 | if (inode && (inode->i_state & I_NEW)) { | ||
84 | setup_inode(inode, cramfs_inode); | ||
85 | unlock_new_inode(inode); | ||
86 | } | ||
87 | } | ||
88 | return inode; | 112 | return inode; |
89 | } | 113 | } |
90 | 114 | ||
@@ -265,6 +289,9 @@ static int cramfs_fill_super(struct super_block *sb, void *data, int silent) | |||
265 | printk(KERN_ERR "cramfs: root is not a directory\n"); | 289 | printk(KERN_ERR "cramfs: root is not a directory\n"); |
266 | goto out; | 290 | goto out; |
267 | } | 291 | } |
292 | /* correct strange, hard-coded permissions of mkcramfs */ | ||
293 | super.root.mode |= (S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); | ||
294 | |||
268 | root_offset = super.root.offset << 2; | 295 | root_offset = super.root.offset << 2; |
269 | if (super.flags & CRAMFS_FLAG_FSID_VERSION_2) { | 296 | if (super.flags & CRAMFS_FLAG_FSID_VERSION_2) { |
270 | sbi->size=super.size; | 297 | sbi->size=super.size; |
@@ -289,7 +316,7 @@ static int cramfs_fill_super(struct super_block *sb, void *data, int silent) | |||
289 | 316 | ||
290 | /* Set it all up.. */ | 317 | /* Set it all up.. */ |
291 | sb->s_op = &cramfs_ops; | 318 | sb->s_op = &cramfs_ops; |
292 | root = get_cramfs_inode(sb, &super.root); | 319 | root = get_cramfs_inode(sb, &super.root, 0); |
293 | if (!root) | 320 | if (!root) |
294 | goto out; | 321 | goto out; |
295 | sb->s_root = d_alloc_root(root); | 322 | sb->s_root = d_alloc_root(root); |
@@ -365,7 +392,7 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
365 | */ | 392 | */ |
366 | namelen = de->namelen << 2; | 393 | namelen = de->namelen << 2; |
367 | memcpy(buf, name, namelen); | 394 | memcpy(buf, name, namelen); |
368 | ino = CRAMINO(de); | 395 | ino = cramino(de, OFFSET(inode) + offset); |
369 | mode = de->mode; | 396 | mode = de->mode; |
370 | mutex_unlock(&read_mutex); | 397 | mutex_unlock(&read_mutex); |
371 | nextoffset = offset + sizeof(*de) + namelen; | 398 | nextoffset = offset + sizeof(*de) + namelen; |
@@ -404,8 +431,9 @@ static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry, s | |||
404 | struct cramfs_inode *de; | 431 | struct cramfs_inode *de; |
405 | char *name; | 432 | char *name; |
406 | int namelen, retval; | 433 | int namelen, retval; |
434 | int dir_off = OFFSET(dir) + offset; | ||
407 | 435 | ||
408 | de = cramfs_read(dir->i_sb, OFFSET(dir) + offset, sizeof(*de)+CRAMFS_MAXPATHLEN); | 436 | de = cramfs_read(dir->i_sb, dir_off, sizeof(*de)+CRAMFS_MAXPATHLEN); |
409 | name = (char *)(de+1); | 437 | name = (char *)(de+1); |
410 | 438 | ||
411 | /* Try to take advantage of sorted directories */ | 439 | /* Try to take advantage of sorted directories */ |
@@ -436,7 +464,7 @@ static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry, s | |||
436 | if (!retval) { | 464 | if (!retval) { |
437 | struct cramfs_inode entry = *de; | 465 | struct cramfs_inode entry = *de; |
438 | mutex_unlock(&read_mutex); | 466 | mutex_unlock(&read_mutex); |
439 | d_add(dentry, get_cramfs_inode(dir->i_sb, &entry)); | 467 | d_add(dentry, get_cramfs_inode(dir->i_sb, &entry, dir_off)); |
440 | return NULL; | 468 | return NULL; |
441 | } | 469 | } |
442 | /* else (retval < 0) */ | 470 | /* else (retval < 0) */ |
diff --git a/fs/dcache.c b/fs/dcache.c index 5699d4c027cb..0c6d5c549d84 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -1320,6 +1320,7 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name) | |||
1320 | __dget_dlock(parent); | 1320 | __dget_dlock(parent); |
1321 | dentry->d_parent = parent; | 1321 | dentry->d_parent = parent; |
1322 | dentry->d_sb = parent->d_sb; | 1322 | dentry->d_sb = parent->d_sb; |
1323 | d_set_d_op(dentry, dentry->d_sb->s_d_op); | ||
1323 | list_add(&dentry->d_u.d_child, &parent->d_subdirs); | 1324 | list_add(&dentry->d_u.d_child, &parent->d_subdirs); |
1324 | spin_unlock(&parent->d_lock); | 1325 | spin_unlock(&parent->d_lock); |
1325 | } | 1326 | } |
@@ -1335,6 +1336,7 @@ struct dentry *d_alloc_pseudo(struct super_block *sb, const struct qstr *name) | |||
1335 | struct dentry *dentry = d_alloc(NULL, name); | 1336 | struct dentry *dentry = d_alloc(NULL, name); |
1336 | if (dentry) { | 1337 | if (dentry) { |
1337 | dentry->d_sb = sb; | 1338 | dentry->d_sb = sb; |
1339 | d_set_d_op(dentry, dentry->d_sb->s_d_op); | ||
1338 | dentry->d_parent = dentry; | 1340 | dentry->d_parent = dentry; |
1339 | dentry->d_flags |= DCACHE_DISCONNECTED; | 1341 | dentry->d_flags |= DCACHE_DISCONNECTED; |
1340 | } | 1342 | } |
@@ -1507,6 +1509,7 @@ struct dentry * d_alloc_root(struct inode * root_inode) | |||
1507 | res = d_alloc(NULL, &name); | 1509 | res = d_alloc(NULL, &name); |
1508 | if (res) { | 1510 | if (res) { |
1509 | res->d_sb = root_inode->i_sb; | 1511 | res->d_sb = root_inode->i_sb; |
1512 | d_set_d_op(res, res->d_sb->s_d_op); | ||
1510 | res->d_parent = res; | 1513 | res->d_parent = res; |
1511 | d_instantiate(res, root_inode); | 1514 | d_instantiate(res, root_inode); |
1512 | } | 1515 | } |
@@ -1567,6 +1570,7 @@ struct dentry *d_obtain_alias(struct inode *inode) | |||
1567 | /* attach a disconnected dentry */ | 1570 | /* attach a disconnected dentry */ |
1568 | spin_lock(&tmp->d_lock); | 1571 | spin_lock(&tmp->d_lock); |
1569 | tmp->d_sb = inode->i_sb; | 1572 | tmp->d_sb = inode->i_sb; |
1573 | d_set_d_op(tmp, tmp->d_sb->s_d_op); | ||
1570 | tmp->d_inode = inode; | 1574 | tmp->d_inode = inode; |
1571 | tmp->d_flags |= DCACHE_DISCONNECTED; | 1575 | tmp->d_flags |= DCACHE_DISCONNECTED; |
1572 | list_add(&tmp->d_alias, &inode->i_dentry); | 1576 | list_add(&tmp->d_alias, &inode->i_dentry); |
@@ -1966,7 +1970,7 @@ out: | |||
1966 | /** | 1970 | /** |
1967 | * d_validate - verify dentry provided from insecure source (deprecated) | 1971 | * d_validate - verify dentry provided from insecure source (deprecated) |
1968 | * @dentry: The dentry alleged to be valid child of @dparent | 1972 | * @dentry: The dentry alleged to be valid child of @dparent |
1969 | * @dparent: The parent dentry (known to be valid) | 1973 | * @parent: The parent dentry (known to be valid) |
1970 | * | 1974 | * |
1971 | * An insecure source has sent us a dentry, here we verify it and dget() it. | 1975 | * An insecure source has sent us a dentry, here we verify it and dget() it. |
1972 | * This is used by ncpfs in its readdir implementation. | 1976 | * This is used by ncpfs in its readdir implementation. |
@@ -2449,8 +2453,7 @@ static int prepend_name(char **buffer, int *buflen, struct qstr *name) | |||
2449 | } | 2453 | } |
2450 | 2454 | ||
2451 | /** | 2455 | /** |
2452 | * Prepend path string to a buffer | 2456 | * prepend_path - Prepend path string to a buffer |
2453 | * | ||
2454 | * @path: the dentry/vfsmount to report | 2457 | * @path: the dentry/vfsmount to report |
2455 | * @root: root vfsmnt/dentry (may be modified by this function) | 2458 | * @root: root vfsmnt/dentry (may be modified by this function) |
2456 | * @buffer: pointer to the end of the buffer | 2459 | * @buffer: pointer to the end of the buffer |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 337352a94751..64ff02330752 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -441,7 +441,6 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
441 | struct qstr lower_name; | 441 | struct qstr lower_name; |
442 | int rc = 0; | 442 | int rc = 0; |
443 | 443 | ||
444 | d_set_d_op(ecryptfs_dentry, &ecryptfs_dops); | ||
445 | if ((ecryptfs_dentry->d_name.len == 1 | 444 | if ((ecryptfs_dentry->d_name.len == 1 |
446 | && !strcmp(ecryptfs_dentry->d_name.name, ".")) | 445 | && !strcmp(ecryptfs_dentry->d_name.name, ".")) |
447 | || (ecryptfs_dentry->d_name.len == 2 | 446 | || (ecryptfs_dentry->d_name.len == 2 |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 351038675376..d3b28abdd6aa 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -141,25 +141,12 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) | |||
141 | return rc; | 141 | return rc; |
142 | } | 142 | } |
143 | 143 | ||
144 | /** | 144 | static struct inode *ecryptfs_get_inode(struct inode *lower_inode, |
145 | * ecryptfs_interpose | 145 | struct super_block *sb) |
146 | * @lower_dentry: Existing dentry in the lower filesystem | ||
147 | * @dentry: ecryptfs' dentry | ||
148 | * @sb: ecryptfs's super_block | ||
149 | * @flags: flags to govern behavior of interpose procedure | ||
150 | * | ||
151 | * Interposes upper and lower dentries. | ||
152 | * | ||
153 | * Returns zero on success; non-zero otherwise | ||
154 | */ | ||
155 | int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry, | ||
156 | struct super_block *sb, u32 flags) | ||
157 | { | 146 | { |
158 | struct inode *lower_inode; | ||
159 | struct inode *inode; | 147 | struct inode *inode; |
160 | int rc = 0; | 148 | int rc = 0; |
161 | 149 | ||
162 | lower_inode = lower_dentry->d_inode; | ||
163 | if (lower_inode->i_sb != ecryptfs_superblock_to_lower(sb)) { | 150 | if (lower_inode->i_sb != ecryptfs_superblock_to_lower(sb)) { |
164 | rc = -EXDEV; | 151 | rc = -EXDEV; |
165 | goto out; | 152 | goto out; |
@@ -189,17 +176,38 @@ int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry, | |||
189 | if (special_file(lower_inode->i_mode)) | 176 | if (special_file(lower_inode->i_mode)) |
190 | init_special_inode(inode, lower_inode->i_mode, | 177 | init_special_inode(inode, lower_inode->i_mode, |
191 | lower_inode->i_rdev); | 178 | lower_inode->i_rdev); |
192 | d_set_d_op(dentry, &ecryptfs_dops); | ||
193 | fsstack_copy_attr_all(inode, lower_inode); | 179 | fsstack_copy_attr_all(inode, lower_inode); |
194 | /* This size will be overwritten for real files w/ headers and | 180 | /* This size will be overwritten for real files w/ headers and |
195 | * other metadata */ | 181 | * other metadata */ |
196 | fsstack_copy_inode_size(inode, lower_inode); | 182 | fsstack_copy_inode_size(inode, lower_inode); |
183 | return inode; | ||
184 | out: | ||
185 | return ERR_PTR(rc); | ||
186 | } | ||
187 | |||
188 | /** | ||
189 | * ecryptfs_interpose | ||
190 | * @lower_dentry: Existing dentry in the lower filesystem | ||
191 | * @dentry: ecryptfs' dentry | ||
192 | * @sb: ecryptfs's super_block | ||
193 | * @flags: flags to govern behavior of interpose procedure | ||
194 | * | ||
195 | * Interposes upper and lower dentries. | ||
196 | * | ||
197 | * Returns zero on success; non-zero otherwise | ||
198 | */ | ||
199 | int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry, | ||
200 | struct super_block *sb, u32 flags) | ||
201 | { | ||
202 | struct inode *lower_inode = lower_dentry->d_inode; | ||
203 | struct inode *inode = ecryptfs_get_inode(lower_inode, sb); | ||
204 | if (IS_ERR(inode)) | ||
205 | return PTR_ERR(inode); | ||
197 | if (flags & ECRYPTFS_INTERPOSE_FLAG_D_ADD) | 206 | if (flags & ECRYPTFS_INTERPOSE_FLAG_D_ADD) |
198 | d_add(dentry, inode); | 207 | d_add(dentry, inode); |
199 | else | 208 | else |
200 | d_instantiate(dentry, inode); | 209 | d_instantiate(dentry, inode); |
201 | out: | 210 | return 0; |
202 | return rc; | ||
203 | } | 211 | } |
204 | 212 | ||
205 | enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig, | 213 | enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig, |
@@ -492,59 +500,11 @@ struct kmem_cache *ecryptfs_sb_info_cache; | |||
492 | static struct file_system_type ecryptfs_fs_type; | 500 | static struct file_system_type ecryptfs_fs_type; |
493 | 501 | ||
494 | /** | 502 | /** |
495 | * ecryptfs_read_super | ||
496 | * @sb: The ecryptfs super block | ||
497 | * @dev_name: The path to mount over | ||
498 | * | ||
499 | * Read the super block of the lower filesystem, and use | ||
500 | * ecryptfs_interpose to create our initial inode and super block | ||
501 | * struct. | ||
502 | */ | ||
503 | static int ecryptfs_read_super(struct super_block *sb, const char *dev_name) | ||
504 | { | ||
505 | struct path path; | ||
506 | int rc; | ||
507 | |||
508 | rc = kern_path(dev_name, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path); | ||
509 | if (rc) { | ||
510 | ecryptfs_printk(KERN_WARNING, "path_lookup() failed\n"); | ||
511 | goto out; | ||
512 | } | ||
513 | if (path.dentry->d_sb->s_type == &ecryptfs_fs_type) { | ||
514 | rc = -EINVAL; | ||
515 | printk(KERN_ERR "Mount on filesystem of type " | ||
516 | "eCryptfs explicitly disallowed due to " | ||
517 | "known incompatibilities\n"); | ||
518 | goto out_free; | ||
519 | } | ||
520 | ecryptfs_set_superblock_lower(sb, path.dentry->d_sb); | ||
521 | sb->s_maxbytes = path.dentry->d_sb->s_maxbytes; | ||
522 | sb->s_blocksize = path.dentry->d_sb->s_blocksize; | ||
523 | ecryptfs_set_dentry_lower(sb->s_root, path.dentry); | ||
524 | ecryptfs_set_dentry_lower_mnt(sb->s_root, path.mnt); | ||
525 | rc = ecryptfs_interpose(path.dentry, sb->s_root, sb, 0); | ||
526 | if (rc) | ||
527 | goto out_free; | ||
528 | rc = 0; | ||
529 | goto out; | ||
530 | out_free: | ||
531 | path_put(&path); | ||
532 | out: | ||
533 | return rc; | ||
534 | } | ||
535 | |||
536 | /** | ||
537 | * ecryptfs_get_sb | 503 | * ecryptfs_get_sb |
538 | * @fs_type | 504 | * @fs_type |
539 | * @flags | 505 | * @flags |
540 | * @dev_name: The path to mount over | 506 | * @dev_name: The path to mount over |
541 | * @raw_data: The options passed into the kernel | 507 | * @raw_data: The options passed into the kernel |
542 | * | ||
543 | * The whole ecryptfs_get_sb process is broken into 3 functions: | ||
544 | * ecryptfs_parse_options(): handle options passed to ecryptfs, if any | ||
545 | * ecryptfs_read_super(): this accesses the lower filesystem and uses | ||
546 | * ecryptfs_interpose to perform most of the linking | ||
547 | * ecryptfs_interpose(): links the lower filesystem into ecryptfs (inode.c) | ||
548 | */ | 508 | */ |
549 | static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags, | 509 | static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags, |
550 | const char *dev_name, void *raw_data) | 510 | const char *dev_name, void *raw_data) |
@@ -553,6 +513,8 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags | |||
553 | struct ecryptfs_sb_info *sbi; | 513 | struct ecryptfs_sb_info *sbi; |
554 | struct ecryptfs_dentry_info *root_info; | 514 | struct ecryptfs_dentry_info *root_info; |
555 | const char *err = "Getting sb failed"; | 515 | const char *err = "Getting sb failed"; |
516 | struct inode *inode; | ||
517 | struct path path; | ||
556 | int rc; | 518 | int rc; |
557 | 519 | ||
558 | sbi = kmem_cache_zalloc(ecryptfs_sb_info_cache, GFP_KERNEL); | 520 | sbi = kmem_cache_zalloc(ecryptfs_sb_info_cache, GFP_KERNEL); |
@@ -575,10 +537,8 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags | |||
575 | 537 | ||
576 | s->s_flags = flags; | 538 | s->s_flags = flags; |
577 | rc = bdi_setup_and_register(&sbi->bdi, "ecryptfs", BDI_CAP_MAP_COPY); | 539 | rc = bdi_setup_and_register(&sbi->bdi, "ecryptfs", BDI_CAP_MAP_COPY); |
578 | if (rc) { | 540 | if (rc) |
579 | deactivate_locked_super(s); | 541 | goto out1; |
580 | goto out; | ||
581 | } | ||
582 | 542 | ||
583 | ecryptfs_set_superblock_private(s, sbi); | 543 | ecryptfs_set_superblock_private(s, sbi); |
584 | s->s_bdi = &sbi->bdi; | 544 | s->s_bdi = &sbi->bdi; |
@@ -586,34 +546,54 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags | |||
586 | /* ->kill_sb() will take care of sbi after that point */ | 546 | /* ->kill_sb() will take care of sbi after that point */ |
587 | sbi = NULL; | 547 | sbi = NULL; |
588 | s->s_op = &ecryptfs_sops; | 548 | s->s_op = &ecryptfs_sops; |
549 | s->s_d_op = &ecryptfs_dops; | ||
589 | 550 | ||
590 | rc = -ENOMEM; | 551 | err = "Reading sb failed"; |
591 | s->s_root = d_alloc(NULL, &(const struct qstr) { | 552 | rc = kern_path(dev_name, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path); |
592 | .hash = 0,.name = "/",.len = 1}); | 553 | if (rc) { |
554 | ecryptfs_printk(KERN_WARNING, "kern_path() failed\n"); | ||
555 | goto out1; | ||
556 | } | ||
557 | if (path.dentry->d_sb->s_type == &ecryptfs_fs_type) { | ||
558 | rc = -EINVAL; | ||
559 | printk(KERN_ERR "Mount on filesystem of type " | ||
560 | "eCryptfs explicitly disallowed due to " | ||
561 | "known incompatibilities\n"); | ||
562 | goto out_free; | ||
563 | } | ||
564 | ecryptfs_set_superblock_lower(s, path.dentry->d_sb); | ||
565 | s->s_maxbytes = path.dentry->d_sb->s_maxbytes; | ||
566 | s->s_blocksize = path.dentry->d_sb->s_blocksize; | ||
567 | |||
568 | inode = ecryptfs_get_inode(path.dentry->d_inode, s); | ||
569 | rc = PTR_ERR(inode); | ||
570 | if (IS_ERR(inode)) | ||
571 | goto out_free; | ||
572 | |||
573 | s->s_root = d_alloc_root(inode); | ||
593 | if (!s->s_root) { | 574 | if (!s->s_root) { |
594 | deactivate_locked_super(s); | 575 | iput(inode); |
595 | goto out; | 576 | rc = -ENOMEM; |
577 | goto out_free; | ||
596 | } | 578 | } |
597 | d_set_d_op(s->s_root, &ecryptfs_dops); | ||
598 | s->s_root->d_sb = s; | ||
599 | s->s_root->d_parent = s->s_root; | ||
600 | 579 | ||
580 | rc = -ENOMEM; | ||
601 | root_info = kmem_cache_zalloc(ecryptfs_dentry_info_cache, GFP_KERNEL); | 581 | root_info = kmem_cache_zalloc(ecryptfs_dentry_info_cache, GFP_KERNEL); |
602 | if (!root_info) { | 582 | if (!root_info) |
603 | deactivate_locked_super(s); | 583 | goto out_free; |
604 | goto out; | 584 | |
605 | } | ||
606 | /* ->kill_sb() will take care of root_info */ | 585 | /* ->kill_sb() will take care of root_info */ |
607 | ecryptfs_set_dentry_private(s->s_root, root_info); | 586 | ecryptfs_set_dentry_private(s->s_root, root_info); |
587 | ecryptfs_set_dentry_lower(s->s_root, path.dentry); | ||
588 | ecryptfs_set_dentry_lower_mnt(s->s_root, path.mnt); | ||
589 | |||
608 | s->s_flags |= MS_ACTIVE; | 590 | s->s_flags |= MS_ACTIVE; |
609 | rc = ecryptfs_read_super(s, dev_name); | ||
610 | if (rc) { | ||
611 | deactivate_locked_super(s); | ||
612 | err = "Reading sb failed"; | ||
613 | goto out; | ||
614 | } | ||
615 | return dget(s->s_root); | 591 | return dget(s->s_root); |
616 | 592 | ||
593 | out_free: | ||
594 | path_put(&path); | ||
595 | out1: | ||
596 | deactivate_locked_super(s); | ||
617 | out: | 597 | out: |
618 | if (sbi) { | 598 | if (sbi) { |
619 | ecryptfs_destroy_mount_crypt_stat(&sbi->mount_crypt_stat); | 599 | ecryptfs_destroy_mount_crypt_stat(&sbi->mount_crypt_stat); |
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 8cf07242067d..cc8a9b7d6064 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -217,7 +217,7 @@ struct ep_send_events_data { | |||
217 | * Configuration options available inside /proc/sys/fs/epoll/ | 217 | * Configuration options available inside /proc/sys/fs/epoll/ |
218 | */ | 218 | */ |
219 | /* Maximum number of epoll watched descriptors, per user */ | 219 | /* Maximum number of epoll watched descriptors, per user */ |
220 | static int max_user_watches __read_mostly; | 220 | static long max_user_watches __read_mostly; |
221 | 221 | ||
222 | /* | 222 | /* |
223 | * This mutex is used to serialize ep_free() and eventpoll_release_file(). | 223 | * This mutex is used to serialize ep_free() and eventpoll_release_file(). |
@@ -240,16 +240,18 @@ static struct kmem_cache *pwq_cache __read_mostly; | |||
240 | 240 | ||
241 | #include <linux/sysctl.h> | 241 | #include <linux/sysctl.h> |
242 | 242 | ||
243 | static int zero; | 243 | static long zero; |
244 | static long long_max = LONG_MAX; | ||
244 | 245 | ||
245 | ctl_table epoll_table[] = { | 246 | ctl_table epoll_table[] = { |
246 | { | 247 | { |
247 | .procname = "max_user_watches", | 248 | .procname = "max_user_watches", |
248 | .data = &max_user_watches, | 249 | .data = &max_user_watches, |
249 | .maxlen = sizeof(int), | 250 | .maxlen = sizeof(max_user_watches), |
250 | .mode = 0644, | 251 | .mode = 0644, |
251 | .proc_handler = proc_dointvec_minmax, | 252 | .proc_handler = proc_doulongvec_minmax, |
252 | .extra1 = &zero, | 253 | .extra1 = &zero, |
254 | .extra2 = &long_max, | ||
253 | }, | 255 | }, |
254 | { } | 256 | { } |
255 | }; | 257 | }; |
@@ -561,7 +563,7 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi) | |||
561 | /* At this point it is safe to free the eventpoll item */ | 563 | /* At this point it is safe to free the eventpoll item */ |
562 | kmem_cache_free(epi_cache, epi); | 564 | kmem_cache_free(epi_cache, epi); |
563 | 565 | ||
564 | atomic_dec(&ep->user->epoll_watches); | 566 | atomic_long_dec(&ep->user->epoll_watches); |
565 | 567 | ||
566 | return 0; | 568 | return 0; |
567 | } | 569 | } |
@@ -898,11 +900,12 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event, | |||
898 | { | 900 | { |
899 | int error, revents, pwake = 0; | 901 | int error, revents, pwake = 0; |
900 | unsigned long flags; | 902 | unsigned long flags; |
903 | long user_watches; | ||
901 | struct epitem *epi; | 904 | struct epitem *epi; |
902 | struct ep_pqueue epq; | 905 | struct ep_pqueue epq; |
903 | 906 | ||
904 | if (unlikely(atomic_read(&ep->user->epoll_watches) >= | 907 | user_watches = atomic_long_read(&ep->user->epoll_watches); |
905 | max_user_watches)) | 908 | if (unlikely(user_watches >= max_user_watches)) |
906 | return -ENOSPC; | 909 | return -ENOSPC; |
907 | if (!(epi = kmem_cache_alloc(epi_cache, GFP_KERNEL))) | 910 | if (!(epi = kmem_cache_alloc(epi_cache, GFP_KERNEL))) |
908 | return -ENOMEM; | 911 | return -ENOMEM; |
@@ -966,7 +969,7 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event, | |||
966 | 969 | ||
967 | spin_unlock_irqrestore(&ep->lock, flags); | 970 | spin_unlock_irqrestore(&ep->lock, flags); |
968 | 971 | ||
969 | atomic_inc(&ep->user->epoll_watches); | 972 | atomic_long_inc(&ep->user->epoll_watches); |
970 | 973 | ||
971 | /* We have to call this outside the lock */ | 974 | /* We have to call this outside the lock */ |
972 | if (pwake) | 975 | if (pwake) |
@@ -1426,6 +1429,7 @@ static int __init eventpoll_init(void) | |||
1426 | */ | 1429 | */ |
1427 | max_user_watches = (((si.totalram - si.totalhigh) / 25) << PAGE_SHIFT) / | 1430 | max_user_watches = (((si.totalram - si.totalhigh) / 25) << PAGE_SHIFT) / |
1428 | EP_ITEM_COST; | 1431 | EP_ITEM_COST; |
1432 | BUG_ON(max_user_watches < 0); | ||
1429 | 1433 | ||
1430 | /* Initialize the structure used to perform safe poll wait head wake ups */ | 1434 | /* Initialize the structure used to perform safe poll wait head wake ups */ |
1431 | ep_nested_calls_init(&poll_safewake_ncalls); | 1435 | ep_nested_calls_init(&poll_safewake_ncalls); |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index b7d0554631e4..7aa767d4f06f 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -364,7 +364,7 @@ static struct block_device *ext3_blkdev_get(dev_t dev, struct super_block *sb) | |||
364 | struct block_device *bdev; | 364 | struct block_device *bdev; |
365 | char b[BDEVNAME_SIZE]; | 365 | char b[BDEVNAME_SIZE]; |
366 | 366 | ||
367 | bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE); | 367 | bdev = blkdev_get_by_dev(dev, FMODE_READ|FMODE_WRITE|FMODE_EXCL, sb); |
368 | if (IS_ERR(bdev)) | 368 | if (IS_ERR(bdev)) |
369 | goto fail; | 369 | goto fail; |
370 | return bdev; | 370 | return bdev; |
@@ -381,8 +381,7 @@ fail: | |||
381 | */ | 381 | */ |
382 | static int ext3_blkdev_put(struct block_device *bdev) | 382 | static int ext3_blkdev_put(struct block_device *bdev) |
383 | { | 383 | { |
384 | bd_release(bdev); | 384 | return blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); |
385 | return blkdev_put(bdev, FMODE_READ|FMODE_WRITE); | ||
386 | } | 385 | } |
387 | 386 | ||
388 | static int ext3_blkdev_remove(struct ext3_sb_info *sbi) | 387 | static int ext3_blkdev_remove(struct ext3_sb_info *sbi) |
@@ -2162,13 +2161,6 @@ static journal_t *ext3_get_dev_journal(struct super_block *sb, | |||
2162 | if (bdev == NULL) | 2161 | if (bdev == NULL) |
2163 | return NULL; | 2162 | return NULL; |
2164 | 2163 | ||
2165 | if (bd_claim(bdev, sb)) { | ||
2166 | ext3_msg(sb, KERN_ERR, | ||
2167 | "error: failed to claim external journal device"); | ||
2168 | blkdev_put(bdev, FMODE_READ|FMODE_WRITE); | ||
2169 | return NULL; | ||
2170 | } | ||
2171 | |||
2172 | blocksize = sb->s_blocksize; | 2164 | blocksize = sb->s_blocksize; |
2173 | hblock = bdev_logical_block_size(bdev); | 2165 | hblock = bdev_logical_block_size(bdev); |
2174 | if (blocksize < hblock) { | 2166 | if (blocksize < hblock) { |
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index bab2387fba43..1de65f572033 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -561,7 +561,7 @@ struct ext4_new_group_data { | |||
561 | #define EXT4_IOC32_SETVERSION_OLD FS_IOC32_SETVERSION | 561 | #define EXT4_IOC32_SETVERSION_OLD FS_IOC32_SETVERSION |
562 | #endif | 562 | #endif |
563 | 563 | ||
564 | /* Max physical block we can addres w/o extents */ | 564 | /* Max physical block we can address w/o extents */ |
565 | #define EXT4_MAX_BLOCK_FILE_PHYS 0xFFFFFFFF | 565 | #define EXT4_MAX_BLOCK_FILE_PHYS 0xFFFFFFFF |
566 | 566 | ||
567 | /* | 567 | /* |
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index e910720e8bb8..c4068f6abf03 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -2845,14 +2845,14 @@ fix_extent_len: | |||
2845 | * to an uninitialized extent. | 2845 | * to an uninitialized extent. |
2846 | * | 2846 | * |
2847 | * Writing to an uninitized extent may result in splitting the uninitialized | 2847 | * Writing to an uninitized extent may result in splitting the uninitialized |
2848 | * extent into multiple /intialized unintialized extents (up to three) | 2848 | * extent into multiple /initialized uninitialized extents (up to three) |
2849 | * There are three possibilities: | 2849 | * There are three possibilities: |
2850 | * a> There is no split required: Entire extent should be uninitialized | 2850 | * a> There is no split required: Entire extent should be uninitialized |
2851 | * b> Splits in two extents: Write is happening at either end of the extent | 2851 | * b> Splits in two extents: Write is happening at either end of the extent |
2852 | * c> Splits in three extents: Somone is writing in middle of the extent | 2852 | * c> Splits in three extents: Somone is writing in middle of the extent |
2853 | * | 2853 | * |
2854 | * One of more index blocks maybe needed if the extent tree grow after | 2854 | * One of more index blocks maybe needed if the extent tree grow after |
2855 | * the unintialized extent split. To prevent ENOSPC occur at the IO | 2855 | * the uninitialized extent split. To prevent ENOSPC occur at the IO |
2856 | * complete, we need to split the uninitialized extent before DIO submit | 2856 | * complete, we need to split the uninitialized extent before DIO submit |
2857 | * the IO. The uninitialized extent called at this time will be split | 2857 | * the IO. The uninitialized extent called at this time will be split |
2858 | * into three uninitialized extent(at most). After IO complete, the part | 2858 | * into three uninitialized extent(at most). After IO complete, the part |
@@ -3644,6 +3644,10 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len) | |||
3644 | struct ext4_map_blocks map; | 3644 | struct ext4_map_blocks map; |
3645 | unsigned int credits, blkbits = inode->i_blkbits; | 3645 | unsigned int credits, blkbits = inode->i_blkbits; |
3646 | 3646 | ||
3647 | /* We only support the FALLOC_FL_KEEP_SIZE mode */ | ||
3648 | if (mode && (mode != FALLOC_FL_KEEP_SIZE)) | ||
3649 | return -EOPNOTSUPP; | ||
3650 | |||
3647 | /* | 3651 | /* |
3648 | * currently supporting (pre)allocate mode for extent-based | 3652 | * currently supporting (pre)allocate mode for extent-based |
3649 | * files _only_ | 3653 | * files _only_ |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index e80fc513eacc..9f7f9e49914f 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/bio.h> | 39 | #include <linux/bio.h> |
40 | #include <linux/workqueue.h> | 40 | #include <linux/workqueue.h> |
41 | #include <linux/kernel.h> | 41 | #include <linux/kernel.h> |
42 | #include <linux/printk.h> | ||
42 | #include <linux/slab.h> | 43 | #include <linux/slab.h> |
43 | #include <linux/ratelimit.h> | 44 | #include <linux/ratelimit.h> |
44 | 45 | ||
@@ -3379,7 +3380,7 @@ int ext4_alloc_da_blocks(struct inode *inode) | |||
3379 | * doing I/O at all. | 3380 | * doing I/O at all. |
3380 | * | 3381 | * |
3381 | * We could call write_cache_pages(), and then redirty all of | 3382 | * We could call write_cache_pages(), and then redirty all of |
3382 | * the pages by calling redirty_page_for_writeback() but that | 3383 | * the pages by calling redirty_page_for_writepage() but that |
3383 | * would be ugly in the extreme. So instead we would need to | 3384 | * would be ugly in the extreme. So instead we would need to |
3384 | * replicate parts of the code in the above functions, | 3385 | * replicate parts of the code in the above functions, |
3385 | * simplifying them becuase we wouldn't actually intend to | 3386 | * simplifying them becuase we wouldn't actually intend to |
@@ -3737,7 +3738,7 @@ static int ext4_set_bh_endio(struct buffer_head *bh, struct inode *inode) | |||
3737 | retry: | 3738 | retry: |
3738 | io_end = ext4_init_io_end(inode, GFP_ATOMIC); | 3739 | io_end = ext4_init_io_end(inode, GFP_ATOMIC); |
3739 | if (!io_end) { | 3740 | if (!io_end) { |
3740 | pr_warning_ratelimited("%s: allocation fail\n", __func__); | 3741 | pr_warn_ratelimited("%s: allocation fail\n", __func__); |
3741 | schedule(); | 3742 | schedule(); |
3742 | goto retry; | 3743 | goto retry; |
3743 | } | 3744 | } |
@@ -3761,9 +3762,9 @@ retry: | |||
3761 | * preallocated extents, and those write extend the file, no need to | 3762 | * preallocated extents, and those write extend the file, no need to |
3762 | * fall back to buffered IO. | 3763 | * fall back to buffered IO. |
3763 | * | 3764 | * |
3764 | * For holes, we fallocate those blocks, mark them as unintialized | 3765 | * For holes, we fallocate those blocks, mark them as uninitialized |
3765 | * If those blocks were preallocated, we mark sure they are splited, but | 3766 | * If those blocks were preallocated, we mark sure they are splited, but |
3766 | * still keep the range to write as unintialized. | 3767 | * still keep the range to write as uninitialized. |
3767 | * | 3768 | * |
3768 | * The unwrritten extents will be converted to written when DIO is completed. | 3769 | * The unwrritten extents will be converted to written when DIO is completed. |
3769 | * For async direct IO, since the IO may still pending when return, we | 3770 | * For async direct IO, since the IO may still pending when return, we |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 29c80f6d8b27..cb10a06775e4 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -657,7 +657,7 @@ static struct block_device *ext4_blkdev_get(dev_t dev, struct super_block *sb) | |||
657 | struct block_device *bdev; | 657 | struct block_device *bdev; |
658 | char b[BDEVNAME_SIZE]; | 658 | char b[BDEVNAME_SIZE]; |
659 | 659 | ||
660 | bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE); | 660 | bdev = blkdev_get_by_dev(dev, FMODE_READ|FMODE_WRITE|FMODE_EXCL, sb); |
661 | if (IS_ERR(bdev)) | 661 | if (IS_ERR(bdev)) |
662 | goto fail; | 662 | goto fail; |
663 | return bdev; | 663 | return bdev; |
@@ -673,8 +673,7 @@ fail: | |||
673 | */ | 673 | */ |
674 | static int ext4_blkdev_put(struct block_device *bdev) | 674 | static int ext4_blkdev_put(struct block_device *bdev) |
675 | { | 675 | { |
676 | bd_release(bdev); | 676 | return blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); |
677 | return blkdev_put(bdev, FMODE_READ|FMODE_WRITE); | ||
678 | } | 677 | } |
679 | 678 | ||
680 | static int ext4_blkdev_remove(struct ext4_sb_info *sbi) | 679 | static int ext4_blkdev_remove(struct ext4_sb_info *sbi) |
@@ -3778,13 +3777,6 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb, | |||
3778 | if (bdev == NULL) | 3777 | if (bdev == NULL) |
3779 | return NULL; | 3778 | return NULL; |
3780 | 3779 | ||
3781 | if (bd_claim(bdev, sb)) { | ||
3782 | ext4_msg(sb, KERN_ERR, | ||
3783 | "failed to claim external journal device"); | ||
3784 | blkdev_put(bdev, FMODE_READ|FMODE_WRITE); | ||
3785 | return NULL; | ||
3786 | } | ||
3787 | |||
3788 | blocksize = sb->s_blocksize; | 3780 | blocksize = sb->s_blocksize; |
3789 | hblock = bdev_logical_block_size(bdev); | 3781 | hblock = bdev_logical_block_size(bdev); |
3790 | if (blocksize < hblock) { | 3782 | if (blocksize < hblock) { |
diff --git a/fs/fat/fat.h b/fs/fat/fat.h index d75a77f85c28..f50408901f7e 100644 --- a/fs/fat/fat.h +++ b/fs/fat/fat.h | |||
@@ -319,7 +319,8 @@ extern struct inode *fat_build_inode(struct super_block *sb, | |||
319 | struct msdos_dir_entry *de, loff_t i_pos); | 319 | struct msdos_dir_entry *de, loff_t i_pos); |
320 | extern int fat_sync_inode(struct inode *inode); | 320 | extern int fat_sync_inode(struct inode *inode); |
321 | extern int fat_fill_super(struct super_block *sb, void *data, int silent, | 321 | extern int fat_fill_super(struct super_block *sb, void *data, int silent, |
322 | const struct inode_operations *fs_dir_inode_ops, int isvfat); | 322 | const struct inode_operations *fs_dir_inode_ops, |
323 | int isvfat, void (*setup)(struct super_block *)); | ||
323 | 324 | ||
324 | extern int fat_flush_inodes(struct super_block *sb, struct inode *i1, | 325 | extern int fat_flush_inodes(struct super_block *sb, struct inode *i1, |
325 | struct inode *i2); | 326 | struct inode *i2); |
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 206351af7c58..86753fe10bd1 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
@@ -703,7 +703,6 @@ static struct dentry *fat_fh_to_dentry(struct super_block *sb, | |||
703 | struct fid *fid, int fh_len, int fh_type) | 703 | struct fid *fid, int fh_len, int fh_type) |
704 | { | 704 | { |
705 | struct inode *inode = NULL; | 705 | struct inode *inode = NULL; |
706 | struct dentry *result; | ||
707 | u32 *fh = fid->raw; | 706 | u32 *fh = fid->raw; |
708 | 707 | ||
709 | if (fh_len < 5 || fh_type != 3) | 708 | if (fh_len < 5 || fh_type != 3) |
@@ -748,10 +747,7 @@ static struct dentry *fat_fh_to_dentry(struct super_block *sb, | |||
748 | * the fat_iget lookup again. If that fails, then we are totally out | 747 | * the fat_iget lookup again. If that fails, then we are totally out |
749 | * of luck. But all that is for another day | 748 | * of luck. But all that is for another day |
750 | */ | 749 | */ |
751 | result = d_obtain_alias(inode); | 750 | return d_obtain_alias(inode); |
752 | if (!IS_ERR(result)) | ||
753 | d_set_d_op(result, sb->s_root->d_op); | ||
754 | return result; | ||
755 | } | 751 | } |
756 | 752 | ||
757 | static int | 753 | static int |
@@ -799,8 +795,6 @@ static struct dentry *fat_get_parent(struct dentry *child) | |||
799 | brelse(bh); | 795 | brelse(bh); |
800 | 796 | ||
801 | parent = d_obtain_alias(inode); | 797 | parent = d_obtain_alias(inode); |
802 | if (!IS_ERR(parent)) | ||
803 | d_set_d_op(parent, sb->s_root->d_op); | ||
804 | out: | 798 | out: |
805 | unlock_super(sb); | 799 | unlock_super(sb); |
806 | 800 | ||
@@ -1244,7 +1238,8 @@ static int fat_read_root(struct inode *inode) | |||
1244 | * Read the super block of an MS-DOS FS. | 1238 | * Read the super block of an MS-DOS FS. |
1245 | */ | 1239 | */ |
1246 | int fat_fill_super(struct super_block *sb, void *data, int silent, | 1240 | int fat_fill_super(struct super_block *sb, void *data, int silent, |
1247 | const struct inode_operations *fs_dir_inode_ops, int isvfat) | 1241 | const struct inode_operations *fs_dir_inode_ops, int isvfat, |
1242 | void (*setup)(struct super_block *)) | ||
1248 | { | 1243 | { |
1249 | struct inode *root_inode = NULL, *fat_inode = NULL; | 1244 | struct inode *root_inode = NULL, *fat_inode = NULL; |
1250 | struct buffer_head *bh; | 1245 | struct buffer_head *bh; |
@@ -1280,6 +1275,8 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, | |||
1280 | if (error) | 1275 | if (error) |
1281 | goto out_fail; | 1276 | goto out_fail; |
1282 | 1277 | ||
1278 | setup(sb); /* flavour-specific stuff that needs options */ | ||
1279 | |||
1283 | error = -EIO; | 1280 | error = -EIO; |
1284 | sb_min_blocksize(sb, 512); | 1281 | sb_min_blocksize(sb, 512); |
1285 | bh = sb_bread(sb, 0); | 1282 | bh = sb_bread(sb, 0); |
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c index 35ffe43afa4b..711499040eb6 100644 --- a/fs/fat/namei_msdos.c +++ b/fs/fat/namei_msdos.c | |||
@@ -227,11 +227,7 @@ static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry, | |||
227 | } | 227 | } |
228 | out: | 228 | out: |
229 | unlock_super(sb); | 229 | unlock_super(sb); |
230 | d_set_d_op(dentry, &msdos_dentry_operations); | 230 | return d_splice_alias(inode, dentry); |
231 | dentry = d_splice_alias(inode, dentry); | ||
232 | if (dentry) | ||
233 | d_set_d_op(dentry, &msdos_dentry_operations); | ||
234 | return dentry; | ||
235 | 231 | ||
236 | error: | 232 | error: |
237 | unlock_super(sb); | 233 | unlock_super(sb); |
@@ -661,21 +657,16 @@ static const struct inode_operations msdos_dir_inode_operations = { | |||
661 | .getattr = fat_getattr, | 657 | .getattr = fat_getattr, |
662 | }; | 658 | }; |
663 | 659 | ||
664 | static int msdos_fill_super(struct super_block *sb, void *data, int silent) | 660 | static void setup(struct super_block *sb) |
665 | { | 661 | { |
666 | int res; | 662 | sb->s_d_op = &msdos_dentry_operations; |
667 | |||
668 | lock_super(sb); | ||
669 | res = fat_fill_super(sb, data, silent, &msdos_dir_inode_operations, 0); | ||
670 | if (res) { | ||
671 | unlock_super(sb); | ||
672 | return res; | ||
673 | } | ||
674 | |||
675 | sb->s_flags |= MS_NOATIME; | 663 | sb->s_flags |= MS_NOATIME; |
676 | d_set_d_op(sb->s_root, &msdos_dentry_operations); | 664 | } |
677 | unlock_super(sb); | 665 | |
678 | return 0; | 666 | static int msdos_fill_super(struct super_block *sb, void *data, int silent) |
667 | { | ||
668 | return fat_fill_super(sb, data, silent, &msdos_dir_inode_operations, | ||
669 | 0, setup); | ||
679 | } | 670 | } |
680 | 671 | ||
681 | static struct dentry *msdos_mount(struct file_system_type *fs_type, | 672 | static struct dentry *msdos_mount(struct file_system_type *fs_type, |
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index e3ffc5e12332..f88f752babd9 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c | |||
@@ -772,13 +772,10 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry, | |||
772 | 772 | ||
773 | out: | 773 | out: |
774 | unlock_super(sb); | 774 | unlock_super(sb); |
775 | d_set_d_op(dentry, sb->s_root->d_op); | ||
776 | dentry->d_time = dentry->d_parent->d_inode->i_version; | 775 | dentry->d_time = dentry->d_parent->d_inode->i_version; |
777 | dentry = d_splice_alias(inode, dentry); | 776 | dentry = d_splice_alias(inode, dentry); |
778 | if (dentry) { | 777 | if (dentry) |
779 | d_set_d_op(dentry, sb->s_root->d_op); | ||
780 | dentry->d_time = dentry->d_parent->d_inode->i_version; | 778 | dentry->d_time = dentry->d_parent->d_inode->i_version; |
781 | } | ||
782 | return dentry; | 779 | return dentry; |
783 | 780 | ||
784 | error: | 781 | error: |
@@ -1066,24 +1063,18 @@ static const struct inode_operations vfat_dir_inode_operations = { | |||
1066 | .getattr = fat_getattr, | 1063 | .getattr = fat_getattr, |
1067 | }; | 1064 | }; |
1068 | 1065 | ||
1069 | static int vfat_fill_super(struct super_block *sb, void *data, int silent) | 1066 | static void setup(struct super_block *sb) |
1070 | { | 1067 | { |
1071 | int res; | ||
1072 | |||
1073 | lock_super(sb); | ||
1074 | res = fat_fill_super(sb, data, silent, &vfat_dir_inode_operations, 1); | ||
1075 | if (res) { | ||
1076 | unlock_super(sb); | ||
1077 | return res; | ||
1078 | } | ||
1079 | |||
1080 | if (MSDOS_SB(sb)->options.name_check != 's') | 1068 | if (MSDOS_SB(sb)->options.name_check != 's') |
1081 | d_set_d_op(sb->s_root, &vfat_ci_dentry_ops); | 1069 | sb->s_d_op = &vfat_ci_dentry_ops; |
1082 | else | 1070 | else |
1083 | d_set_d_op(sb->s_root, &vfat_dentry_ops); | 1071 | sb->s_d_op = &vfat_dentry_ops; |
1072 | } | ||
1084 | 1073 | ||
1085 | unlock_super(sb); | 1074 | static int vfat_fill_super(struct super_block *sb, void *data, int silent) |
1086 | return 0; | 1075 | { |
1076 | return fat_fill_super(sb, data, silent, &vfat_dir_inode_operations, | ||
1077 | 1, setup); | ||
1087 | } | 1078 | } |
1088 | 1079 | ||
1089 | static struct dentry *vfat_mount(struct file_system_type *fs_type, | 1080 | static struct dentry *vfat_mount(struct file_system_type *fs_type, |
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 3d06ccc953aa..59c6e4956786 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -84,13 +84,9 @@ static inline struct inode *wb_inode(struct list_head *head) | |||
84 | return list_entry(head, struct inode, i_wb_list); | 84 | return list_entry(head, struct inode, i_wb_list); |
85 | } | 85 | } |
86 | 86 | ||
87 | static void bdi_queue_work(struct backing_dev_info *bdi, | 87 | /* Wakeup flusher thread or forker thread to fork it. Requires bdi->wb_lock. */ |
88 | struct wb_writeback_work *work) | 88 | static void bdi_wakeup_flusher(struct backing_dev_info *bdi) |
89 | { | 89 | { |
90 | trace_writeback_queue(bdi, work); | ||
91 | |||
92 | spin_lock_bh(&bdi->wb_lock); | ||
93 | list_add_tail(&work->list, &bdi->work_list); | ||
94 | if (bdi->wb.task) { | 90 | if (bdi->wb.task) { |
95 | wake_up_process(bdi->wb.task); | 91 | wake_up_process(bdi->wb.task); |
96 | } else { | 92 | } else { |
@@ -98,15 +94,26 @@ static void bdi_queue_work(struct backing_dev_info *bdi, | |||
98 | * The bdi thread isn't there, wake up the forker thread which | 94 | * The bdi thread isn't there, wake up the forker thread which |
99 | * will create and run it. | 95 | * will create and run it. |
100 | */ | 96 | */ |
101 | trace_writeback_nothread(bdi, work); | ||
102 | wake_up_process(default_backing_dev_info.wb.task); | 97 | wake_up_process(default_backing_dev_info.wb.task); |
103 | } | 98 | } |
99 | } | ||
100 | |||
101 | static void bdi_queue_work(struct backing_dev_info *bdi, | ||
102 | struct wb_writeback_work *work) | ||
103 | { | ||
104 | trace_writeback_queue(bdi, work); | ||
105 | |||
106 | spin_lock_bh(&bdi->wb_lock); | ||
107 | list_add_tail(&work->list, &bdi->work_list); | ||
108 | if (!bdi->wb.task) | ||
109 | trace_writeback_nothread(bdi, work); | ||
110 | bdi_wakeup_flusher(bdi); | ||
104 | spin_unlock_bh(&bdi->wb_lock); | 111 | spin_unlock_bh(&bdi->wb_lock); |
105 | } | 112 | } |
106 | 113 | ||
107 | static void | 114 | static void |
108 | __bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages, | 115 | __bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages, |
109 | bool range_cyclic, bool for_background) | 116 | bool range_cyclic) |
110 | { | 117 | { |
111 | struct wb_writeback_work *work; | 118 | struct wb_writeback_work *work; |
112 | 119 | ||
@@ -126,7 +133,6 @@ __bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages, | |||
126 | work->sync_mode = WB_SYNC_NONE; | 133 | work->sync_mode = WB_SYNC_NONE; |
127 | work->nr_pages = nr_pages; | 134 | work->nr_pages = nr_pages; |
128 | work->range_cyclic = range_cyclic; | 135 | work->range_cyclic = range_cyclic; |
129 | work->for_background = for_background; | ||
130 | 136 | ||
131 | bdi_queue_work(bdi, work); | 137 | bdi_queue_work(bdi, work); |
132 | } | 138 | } |
@@ -144,7 +150,7 @@ __bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages, | |||
144 | */ | 150 | */ |
145 | void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages) | 151 | void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages) |
146 | { | 152 | { |
147 | __bdi_start_writeback(bdi, nr_pages, true, false); | 153 | __bdi_start_writeback(bdi, nr_pages, true); |
148 | } | 154 | } |
149 | 155 | ||
150 | /** | 156 | /** |
@@ -152,13 +158,21 @@ void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages) | |||
152 | * @bdi: the backing device to write from | 158 | * @bdi: the backing device to write from |
153 | * | 159 | * |
154 | * Description: | 160 | * Description: |
155 | * This does WB_SYNC_NONE background writeback. The IO is only | 161 | * This makes sure WB_SYNC_NONE background writeback happens. When |
156 | * started when this function returns, we make no guarentees on | 162 | * this function returns, it is only guaranteed that for given BDI |
157 | * completion. Caller need not hold sb s_umount semaphore. | 163 | * some IO is happening if we are over background dirty threshold. |
164 | * Caller need not hold sb s_umount semaphore. | ||
158 | */ | 165 | */ |
159 | void bdi_start_background_writeback(struct backing_dev_info *bdi) | 166 | void bdi_start_background_writeback(struct backing_dev_info *bdi) |
160 | { | 167 | { |
161 | __bdi_start_writeback(bdi, LONG_MAX, true, true); | 168 | /* |
169 | * We just wake up the flusher thread. It will perform background | ||
170 | * writeback as soon as there is no other work to do. | ||
171 | */ | ||
172 | trace_writeback_wake_background(bdi); | ||
173 | spin_lock_bh(&bdi->wb_lock); | ||
174 | bdi_wakeup_flusher(bdi); | ||
175 | spin_unlock_bh(&bdi->wb_lock); | ||
162 | } | 176 | } |
163 | 177 | ||
164 | /* | 178 | /* |
@@ -616,6 +630,7 @@ static long wb_writeback(struct bdi_writeback *wb, | |||
616 | }; | 630 | }; |
617 | unsigned long oldest_jif; | 631 | unsigned long oldest_jif; |
618 | long wrote = 0; | 632 | long wrote = 0; |
633 | long write_chunk; | ||
619 | struct inode *inode; | 634 | struct inode *inode; |
620 | 635 | ||
621 | if (wbc.for_kupdate) { | 636 | if (wbc.for_kupdate) { |
@@ -628,6 +643,24 @@ static long wb_writeback(struct bdi_writeback *wb, | |||
628 | wbc.range_end = LLONG_MAX; | 643 | wbc.range_end = LLONG_MAX; |
629 | } | 644 | } |
630 | 645 | ||
646 | /* | ||
647 | * WB_SYNC_ALL mode does livelock avoidance by syncing dirty | ||
648 | * inodes/pages in one big loop. Setting wbc.nr_to_write=LONG_MAX | ||
649 | * here avoids calling into writeback_inodes_wb() more than once. | ||
650 | * | ||
651 | * The intended call sequence for WB_SYNC_ALL writeback is: | ||
652 | * | ||
653 | * wb_writeback() | ||
654 | * __writeback_inodes_sb() <== called only once | ||
655 | * write_cache_pages() <== called once for each inode | ||
656 | * (quickly) tag currently dirty pages | ||
657 | * (maybe slowly) sync all tagged pages | ||
658 | */ | ||
659 | if (wbc.sync_mode == WB_SYNC_NONE) | ||
660 | write_chunk = MAX_WRITEBACK_PAGES; | ||
661 | else | ||
662 | write_chunk = LONG_MAX; | ||
663 | |||
631 | wbc.wb_start = jiffies; /* livelock avoidance */ | 664 | wbc.wb_start = jiffies; /* livelock avoidance */ |
632 | for (;;) { | 665 | for (;;) { |
633 | /* | 666 | /* |
@@ -637,6 +670,16 @@ static long wb_writeback(struct bdi_writeback *wb, | |||
637 | break; | 670 | break; |
638 | 671 | ||
639 | /* | 672 | /* |
673 | * Background writeout and kupdate-style writeback may | ||
674 | * run forever. Stop them if there is other work to do | ||
675 | * so that e.g. sync can proceed. They'll be restarted | ||
676 | * after the other works are all done. | ||
677 | */ | ||
678 | if ((work->for_background || work->for_kupdate) && | ||
679 | !list_empty(&wb->bdi->work_list)) | ||
680 | break; | ||
681 | |||
682 | /* | ||
640 | * For background writeout, stop when we are below the | 683 | * For background writeout, stop when we are below the |
641 | * background dirty threshold | 684 | * background dirty threshold |
642 | */ | 685 | */ |
@@ -644,7 +687,7 @@ static long wb_writeback(struct bdi_writeback *wb, | |||
644 | break; | 687 | break; |
645 | 688 | ||
646 | wbc.more_io = 0; | 689 | wbc.more_io = 0; |
647 | wbc.nr_to_write = MAX_WRITEBACK_PAGES; | 690 | wbc.nr_to_write = write_chunk; |
648 | wbc.pages_skipped = 0; | 691 | wbc.pages_skipped = 0; |
649 | 692 | ||
650 | trace_wbc_writeback_start(&wbc, wb->bdi); | 693 | trace_wbc_writeback_start(&wbc, wb->bdi); |
@@ -654,8 +697,8 @@ static long wb_writeback(struct bdi_writeback *wb, | |||
654 | writeback_inodes_wb(wb, &wbc); | 697 | writeback_inodes_wb(wb, &wbc); |
655 | trace_wbc_writeback_written(&wbc, wb->bdi); | 698 | trace_wbc_writeback_written(&wbc, wb->bdi); |
656 | 699 | ||
657 | work->nr_pages -= MAX_WRITEBACK_PAGES - wbc.nr_to_write; | 700 | work->nr_pages -= write_chunk - wbc.nr_to_write; |
658 | wrote += MAX_WRITEBACK_PAGES - wbc.nr_to_write; | 701 | wrote += write_chunk - wbc.nr_to_write; |
659 | 702 | ||
660 | /* | 703 | /* |
661 | * If we consumed everything, see if we have more | 704 | * If we consumed everything, see if we have more |
@@ -670,7 +713,7 @@ static long wb_writeback(struct bdi_writeback *wb, | |||
670 | /* | 713 | /* |
671 | * Did we write something? Try for more | 714 | * Did we write something? Try for more |
672 | */ | 715 | */ |
673 | if (wbc.nr_to_write < MAX_WRITEBACK_PAGES) | 716 | if (wbc.nr_to_write < write_chunk) |
674 | continue; | 717 | continue; |
675 | /* | 718 | /* |
676 | * Nothing written. Wait for some inode to | 719 | * Nothing written. Wait for some inode to |
@@ -718,6 +761,23 @@ static unsigned long get_nr_dirty_pages(void) | |||
718 | get_nr_dirty_inodes(); | 761 | get_nr_dirty_inodes(); |
719 | } | 762 | } |
720 | 763 | ||
764 | static long wb_check_background_flush(struct bdi_writeback *wb) | ||
765 | { | ||
766 | if (over_bground_thresh()) { | ||
767 | |||
768 | struct wb_writeback_work work = { | ||
769 | .nr_pages = LONG_MAX, | ||
770 | .sync_mode = WB_SYNC_NONE, | ||
771 | .for_background = 1, | ||
772 | .range_cyclic = 1, | ||
773 | }; | ||
774 | |||
775 | return wb_writeback(wb, &work); | ||
776 | } | ||
777 | |||
778 | return 0; | ||
779 | } | ||
780 | |||
721 | static long wb_check_old_data_flush(struct bdi_writeback *wb) | 781 | static long wb_check_old_data_flush(struct bdi_writeback *wb) |
722 | { | 782 | { |
723 | unsigned long expired; | 783 | unsigned long expired; |
@@ -787,6 +847,7 @@ long wb_do_writeback(struct bdi_writeback *wb, int force_wait) | |||
787 | * Check for periodic writeback, kupdated() style | 847 | * Check for periodic writeback, kupdated() style |
788 | */ | 848 | */ |
789 | wrote += wb_check_old_data_flush(wb); | 849 | wrote += wb_check_old_data_flush(wb); |
850 | wrote += wb_check_background_flush(wb); | ||
790 | clear_bit(BDI_writeback_running, &wb->bdi->state); | 851 | clear_bit(BDI_writeback_running, &wb->bdi->state); |
791 | 852 | ||
792 | return wrote; | 853 | return wrote; |
@@ -873,7 +934,7 @@ void wakeup_flusher_threads(long nr_pages) | |||
873 | list_for_each_entry_rcu(bdi, &bdi_list, bdi_list) { | 934 | list_for_each_entry_rcu(bdi, &bdi_list, bdi_list) { |
874 | if (!bdi_has_dirty_io(bdi)) | 935 | if (!bdi_has_dirty_io(bdi)) |
875 | continue; | 936 | continue; |
876 | __bdi_start_writeback(bdi, nr_pages, false, false); | 937 | __bdi_start_writeback(bdi, nr_pages, false); |
877 | } | 938 | } |
878 | rcu_read_unlock(); | 939 | rcu_read_unlock(); |
879 | } | 940 | } |
@@ -1164,7 +1225,7 @@ EXPORT_SYMBOL(writeback_inodes_sb_nr_if_idle); | |||
1164 | * @sb: the superblock | 1225 | * @sb: the superblock |
1165 | * | 1226 | * |
1166 | * This function writes and waits on any dirty inode belonging to this | 1227 | * This function writes and waits on any dirty inode belonging to this |
1167 | * super_block. The number of pages synced is returned. | 1228 | * super_block. |
1168 | */ | 1229 | */ |
1169 | void sync_inodes_sb(struct super_block *sb) | 1230 | void sync_inodes_sb(struct super_block *sb) |
1170 | { | 1231 | { |
@@ -1242,11 +1303,11 @@ int sync_inode(struct inode *inode, struct writeback_control *wbc) | |||
1242 | EXPORT_SYMBOL(sync_inode); | 1303 | EXPORT_SYMBOL(sync_inode); |
1243 | 1304 | ||
1244 | /** | 1305 | /** |
1245 | * sync_inode - write an inode to disk | 1306 | * sync_inode_metadata - write an inode to disk |
1246 | * @inode: the inode to sync | 1307 | * @inode: the inode to sync |
1247 | * @wait: wait for I/O to complete. | 1308 | * @wait: wait for I/O to complete. |
1248 | * | 1309 | * |
1249 | * Write an inode to disk and adjust it's dirty state after completion. | 1310 | * Write an inode to disk and adjust its dirty state after completion. |
1250 | * | 1311 | * |
1251 | * Note: only writes the actual inode, no associated data or other metadata. | 1312 | * Note: only writes the actual inode, no associated data or other metadata. |
1252 | */ | 1313 | */ |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 042af7346ec1..bfed8447ed80 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -350,7 +350,6 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, | |||
350 | } | 350 | } |
351 | 351 | ||
352 | entry = newent ? newent : entry; | 352 | entry = newent ? newent : entry; |
353 | d_set_d_op(entry, &fuse_dentry_operations); | ||
354 | if (outarg_valid) | 353 | if (outarg_valid) |
355 | fuse_change_entry_timeout(entry, &outarg); | 354 | fuse_change_entry_timeout(entry, &outarg); |
356 | else | 355 | else |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index f62b32cffea9..9e3f68cc1bd1 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -617,10 +617,8 @@ static struct dentry *fuse_get_dentry(struct super_block *sb, | |||
617 | goto out_iput; | 617 | goto out_iput; |
618 | 618 | ||
619 | entry = d_obtain_alias(inode); | 619 | entry = d_obtain_alias(inode); |
620 | if (!IS_ERR(entry) && get_node_id(inode) != FUSE_ROOT_ID) { | 620 | if (!IS_ERR(entry) && get_node_id(inode) != FUSE_ROOT_ID) |
621 | d_set_d_op(entry, &fuse_dentry_operations); | ||
622 | fuse_invalidate_entry_cache(entry); | 621 | fuse_invalidate_entry_cache(entry); |
623 | } | ||
624 | 622 | ||
625 | return entry; | 623 | return entry; |
626 | 624 | ||
@@ -719,10 +717,8 @@ static struct dentry *fuse_get_parent(struct dentry *child) | |||
719 | } | 717 | } |
720 | 718 | ||
721 | parent = d_obtain_alias(inode); | 719 | parent = d_obtain_alias(inode); |
722 | if (!IS_ERR(parent) && get_node_id(inode) != FUSE_ROOT_ID) { | 720 | if (!IS_ERR(parent) && get_node_id(inode) != FUSE_ROOT_ID) |
723 | d_set_d_op(parent, &fuse_dentry_operations); | ||
724 | fuse_invalidate_entry_cache(parent); | 721 | fuse_invalidate_entry_cache(parent); |
725 | } | ||
726 | 722 | ||
727 | return parent; | 723 | return parent; |
728 | } | 724 | } |
@@ -989,6 +985,8 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
989 | iput(root); | 985 | iput(root); |
990 | goto err_put_conn; | 986 | goto err_put_conn; |
991 | } | 987 | } |
988 | /* only now - we want root dentry with NULL ->d_op */ | ||
989 | sb->s_d_op = &fuse_dentry_operations; | ||
992 | 990 | ||
993 | init_req = fuse_request_alloc(); | 991 | init_req = fuse_request_alloc(); |
994 | if (!init_req) | 992 | if (!init_req) |
diff --git a/fs/gfs2/export.c b/fs/gfs2/export.c index 97012ecff560..9023db8184f9 100644 --- a/fs/gfs2/export.c +++ b/fs/gfs2/export.c | |||
@@ -126,12 +126,7 @@ static int gfs2_get_name(struct dentry *parent, char *name, | |||
126 | 126 | ||
127 | static struct dentry *gfs2_get_parent(struct dentry *child) | 127 | static struct dentry *gfs2_get_parent(struct dentry *child) |
128 | { | 128 | { |
129 | struct dentry *dentry; | 129 | return d_obtain_alias(gfs2_lookupi(child->d_inode, &gfs2_qdotdot, 1)); |
130 | |||
131 | dentry = d_obtain_alias(gfs2_lookupi(child->d_inode, &gfs2_qdotdot, 1)); | ||
132 | if (!IS_ERR(dentry)) | ||
133 | d_set_d_op(dentry, &gfs2_dops); | ||
134 | return dentry; | ||
135 | } | 130 | } |
136 | 131 | ||
137 | static struct dentry *gfs2_get_dentry(struct super_block *sb, | 132 | static struct dentry *gfs2_get_dentry(struct super_block *sb, |
@@ -139,7 +134,6 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, | |||
139 | { | 134 | { |
140 | struct gfs2_sbd *sdp = sb->s_fs_info; | 135 | struct gfs2_sbd *sdp = sb->s_fs_info; |
141 | struct inode *inode; | 136 | struct inode *inode; |
142 | struct dentry *dentry; | ||
143 | 137 | ||
144 | inode = gfs2_ilookup(sb, inum->no_addr); | 138 | inode = gfs2_ilookup(sb, inum->no_addr); |
145 | if (inode) { | 139 | if (inode) { |
@@ -156,10 +150,7 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, | |||
156 | return ERR_CAST(inode); | 150 | return ERR_CAST(inode); |
157 | 151 | ||
158 | out_inode: | 152 | out_inode: |
159 | dentry = d_obtain_alias(inode); | 153 | return d_obtain_alias(inode); |
160 | if (!IS_ERR(dentry)) | ||
161 | d_set_d_op(dentry, &gfs2_dops); | ||
162 | return dentry; | ||
163 | } | 154 | } |
164 | 155 | ||
165 | static struct dentry *gfs2_fh_to_dentry(struct super_block *sb, struct fid *fid, | 156 | static struct dentry *gfs2_fh_to_dentry(struct super_block *sb, struct fid *fid, |
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 2aeabd4218cc..777927ce6f79 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c | |||
@@ -440,7 +440,6 @@ static int gfs2_lookup_root(struct super_block *sb, struct dentry **dptr, | |||
440 | iput(inode); | 440 | iput(inode); |
441 | return -ENOMEM; | 441 | return -ENOMEM; |
442 | } | 442 | } |
443 | d_set_d_op(dentry, &gfs2_dops); | ||
444 | *dptr = dentry; | 443 | *dptr = dentry; |
445 | return 0; | 444 | return 0; |
446 | } | 445 | } |
@@ -1106,6 +1105,7 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent | |||
1106 | 1105 | ||
1107 | sb->s_magic = GFS2_MAGIC; | 1106 | sb->s_magic = GFS2_MAGIC; |
1108 | sb->s_op = &gfs2_super_ops; | 1107 | sb->s_op = &gfs2_super_ops; |
1108 | sb->s_d_op = &gfs2_dops; | ||
1109 | sb->s_export_op = &gfs2_export_ops; | 1109 | sb->s_export_op = &gfs2_export_ops; |
1110 | sb->s_xattr = gfs2_xattr_handlers; | 1110 | sb->s_xattr = gfs2_xattr_handlers; |
1111 | sb->s_qcop = &gfs2_quotactl_ops; | 1111 | sb->s_qcop = &gfs2_quotactl_ops; |
@@ -1268,7 +1268,7 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags, | |||
1268 | { | 1268 | { |
1269 | struct block_device *bdev; | 1269 | struct block_device *bdev; |
1270 | struct super_block *s; | 1270 | struct super_block *s; |
1271 | fmode_t mode = FMODE_READ; | 1271 | fmode_t mode = FMODE_READ | FMODE_EXCL; |
1272 | int error; | 1272 | int error; |
1273 | struct gfs2_args args; | 1273 | struct gfs2_args args; |
1274 | struct gfs2_sbd *sdp; | 1274 | struct gfs2_sbd *sdp; |
@@ -1276,7 +1276,7 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags, | |||
1276 | if (!(flags & MS_RDONLY)) | 1276 | if (!(flags & MS_RDONLY)) |
1277 | mode |= FMODE_WRITE; | 1277 | mode |= FMODE_WRITE; |
1278 | 1278 | ||
1279 | bdev = open_bdev_exclusive(dev_name, mode, fs_type); | 1279 | bdev = blkdev_get_by_path(dev_name, mode, fs_type); |
1280 | if (IS_ERR(bdev)) | 1280 | if (IS_ERR(bdev)) |
1281 | return ERR_CAST(bdev); | 1281 | return ERR_CAST(bdev); |
1282 | 1282 | ||
@@ -1298,7 +1298,7 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags, | |||
1298 | goto error_bdev; | 1298 | goto error_bdev; |
1299 | 1299 | ||
1300 | if (s->s_root) | 1300 | if (s->s_root) |
1301 | close_bdev_exclusive(bdev, mode); | 1301 | blkdev_put(bdev, mode); |
1302 | 1302 | ||
1303 | memset(&args, 0, sizeof(args)); | 1303 | memset(&args, 0, sizeof(args)); |
1304 | args.ar_quota = GFS2_QUOTA_DEFAULT; | 1304 | args.ar_quota = GFS2_QUOTA_DEFAULT; |
@@ -1342,7 +1342,7 @@ error_super: | |||
1342 | deactivate_locked_super(s); | 1342 | deactivate_locked_super(s); |
1343 | return ERR_PTR(error); | 1343 | return ERR_PTR(error); |
1344 | error_bdev: | 1344 | error_bdev: |
1345 | close_bdev_exclusive(bdev, mode); | 1345 | blkdev_put(bdev, mode); |
1346 | return ERR_PTR(error); | 1346 | return ERR_PTR(error); |
1347 | } | 1347 | } |
1348 | 1348 | ||
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c index 1501db4f0e6d..040b5a2e6556 100644 --- a/fs/gfs2/ops_inode.c +++ b/fs/gfs2/ops_inode.c | |||
@@ -106,8 +106,6 @@ static struct dentry *gfs2_lookup(struct inode *dir, struct dentry *dentry, | |||
106 | { | 106 | { |
107 | struct inode *inode = NULL; | 107 | struct inode *inode = NULL; |
108 | 108 | ||
109 | d_set_d_op(dentry, &gfs2_dops); | ||
110 | |||
111 | inode = gfs2_lookupi(dir, &dentry->d_name, 0); | 109 | inode = gfs2_lookupi(dir, &dentry->d_name, 0); |
112 | if (inode && IS_ERR(inode)) | 110 | if (inode && IS_ERR(inode)) |
113 | return ERR_CAST(inode); | 111 | return ERR_CAST(inode); |
@@ -1427,6 +1425,10 @@ static long gfs2_fallocate(struct inode *inode, int mode, loff_t offset, | |||
1427 | loff_t next = (offset + len - 1) >> sdp->sd_sb.sb_bsize_shift; | 1425 | loff_t next = (offset + len - 1) >> sdp->sd_sb.sb_bsize_shift; |
1428 | next = (next + 1) << sdp->sd_sb.sb_bsize_shift; | 1426 | next = (next + 1) << sdp->sd_sb.sb_bsize_shift; |
1429 | 1427 | ||
1428 | /* We only support the FALLOC_FL_KEEP_SIZE mode */ | ||
1429 | if (mode && (mode != FALLOC_FL_KEEP_SIZE)) | ||
1430 | return -EOPNOTSUPP; | ||
1431 | |||
1430 | offset = (offset >> sdp->sd_sb.sb_bsize_shift) << | 1432 | offset = (offset >> sdp->sd_sb.sb_bsize_shift) << |
1431 | sdp->sd_sb.sb_bsize_shift; | 1433 | sdp->sd_sb.sb_bsize_shift; |
1432 | 1434 | ||
diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c index ea4aefe7c652..afa66aaa2237 100644 --- a/fs/hfs/dir.c +++ b/fs/hfs/dir.c | |||
@@ -25,8 +25,6 @@ static struct dentry *hfs_lookup(struct inode *dir, struct dentry *dentry, | |||
25 | struct inode *inode = NULL; | 25 | struct inode *inode = NULL; |
26 | int res; | 26 | int res; |
27 | 27 | ||
28 | d_set_d_op(dentry, &hfs_dentry_operations); | ||
29 | |||
30 | hfs_find_init(HFS_SB(dir->i_sb)->cat_tree, &fd); | 28 | hfs_find_init(HFS_SB(dir->i_sb)->cat_tree, &fd); |
31 | hfs_cat_build_key(dir->i_sb, fd.search_key, dir->i_ino, &dentry->d_name); | 29 | hfs_cat_build_key(dir->i_sb, fd.search_key, dir->i_ino, &dentry->d_name); |
32 | res = hfs_brec_read(&fd, &rec, sizeof(rec)); | 30 | res = hfs_brec_read(&fd, &rec, sizeof(rec)); |
diff --git a/fs/hfs/super.c b/fs/hfs/super.c index 0bef62aa4f42..1b55f704fb22 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c | |||
@@ -429,13 +429,12 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent) | |||
429 | if (!root_inode) | 429 | if (!root_inode) |
430 | goto bail_no_root; | 430 | goto bail_no_root; |
431 | 431 | ||
432 | sb->s_d_op = &hfs_dentry_operations; | ||
432 | res = -ENOMEM; | 433 | res = -ENOMEM; |
433 | sb->s_root = d_alloc_root(root_inode); | 434 | sb->s_root = d_alloc_root(root_inode); |
434 | if (!sb->s_root) | 435 | if (!sb->s_root) |
435 | goto bail_iput; | 436 | goto bail_iput; |
436 | 437 | ||
437 | d_set_d_op(sb->s_root, &hfs_dentry_operations); | ||
438 | |||
439 | /* everything's okay */ | 438 | /* everything's okay */ |
440 | return 0; | 439 | return 0; |
441 | 440 | ||
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index f896dc843026..4df5059c25da 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c | |||
@@ -37,7 +37,6 @@ static struct dentry *hfsplus_lookup(struct inode *dir, struct dentry *dentry, | |||
37 | 37 | ||
38 | sb = dir->i_sb; | 38 | sb = dir->i_sb; |
39 | 39 | ||
40 | d_set_d_op(dentry, &hfsplus_dentry_operations); | ||
41 | dentry->d_fsdata = NULL; | 40 | dentry->d_fsdata = NULL; |
42 | hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd); | 41 | hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd); |
43 | hfsplus_cat_build_key(sb, fd.search_key, dir->i_ino, &dentry->d_name); | 42 | hfsplus_cat_build_key(sb, fd.search_key, dir->i_ino, &dentry->d_name); |
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 6ee6ad20acf2..9a3b4795f43c 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c | |||
@@ -444,13 +444,13 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
444 | err = PTR_ERR(root); | 444 | err = PTR_ERR(root); |
445 | goto cleanup; | 445 | goto cleanup; |
446 | } | 446 | } |
447 | sb->s_d_op = &hfsplus_dentry_operations; | ||
447 | sb->s_root = d_alloc_root(root); | 448 | sb->s_root = d_alloc_root(root); |
448 | if (!sb->s_root) { | 449 | if (!sb->s_root) { |
449 | iput(root); | 450 | iput(root); |
450 | err = -ENOMEM; | 451 | err = -ENOMEM; |
451 | goto cleanup; | 452 | goto cleanup; |
452 | } | 453 | } |
453 | d_set_d_op(sb->s_root, &hfsplus_dentry_operations); | ||
454 | 454 | ||
455 | str.len = sizeof(HFSP_HIDDENDIR_NAME) - 1; | 455 | str.len = sizeof(HFSP_HIDDENDIR_NAME) - 1; |
456 | str.name = HFSP_HIDDENDIR_NAME; | 456 | str.name = HFSP_HIDDENDIR_NAME; |
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index d3244d949a4e..2638c834ed28 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c | |||
@@ -612,7 +612,6 @@ struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry, | |||
612 | goto out_put; | 612 | goto out_put; |
613 | 613 | ||
614 | d_add(dentry, inode); | 614 | d_add(dentry, inode); |
615 | d_set_d_op(dentry, &hostfs_dentry_ops); | ||
616 | return NULL; | 615 | return NULL; |
617 | 616 | ||
618 | out_put: | 617 | out_put: |
@@ -922,6 +921,7 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) | |||
922 | sb->s_blocksize_bits = 10; | 921 | sb->s_blocksize_bits = 10; |
923 | sb->s_magic = HOSTFS_SUPER_MAGIC; | 922 | sb->s_magic = HOSTFS_SUPER_MAGIC; |
924 | sb->s_op = &hostfs_sbops; | 923 | sb->s_op = &hostfs_sbops; |
924 | sb->s_d_op = &hostfs_dentry_ops; | ||
925 | sb->s_maxbytes = MAX_LFS_FILESIZE; | 925 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
926 | 926 | ||
927 | /* NULL is printed as <NULL> by sprintf: avoid that. */ | 927 | /* NULL is printed as <NULL> by sprintf: avoid that. */ |
diff --git a/fs/hpfs/dentry.c b/fs/hpfs/dentry.c index 32c13a94e1e9..05d4816e4e77 100644 --- a/fs/hpfs/dentry.c +++ b/fs/hpfs/dentry.c | |||
@@ -58,12 +58,7 @@ static int hpfs_compare_dentry(const struct dentry *parent, | |||
58 | return 0; | 58 | return 0; |
59 | } | 59 | } |
60 | 60 | ||
61 | static const struct dentry_operations hpfs_dentry_operations = { | 61 | const struct dentry_operations hpfs_dentry_operations = { |
62 | .d_hash = hpfs_hash_dentry, | 62 | .d_hash = hpfs_hash_dentry, |
63 | .d_compare = hpfs_compare_dentry, | 63 | .d_compare = hpfs_compare_dentry, |
64 | }; | 64 | }; |
65 | |||
66 | void hpfs_set_dentry_operations(struct dentry *dentry) | ||
67 | { | ||
68 | d_set_d_op(dentry, &hpfs_dentry_operations); | ||
69 | } | ||
diff --git a/fs/hpfs/dir.c b/fs/hpfs/dir.c index 2338130cceba..d32f63a569f7 100644 --- a/fs/hpfs/dir.c +++ b/fs/hpfs/dir.c | |||
@@ -298,7 +298,6 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, struct name | |||
298 | 298 | ||
299 | end: | 299 | end: |
300 | end_add: | 300 | end_add: |
301 | hpfs_set_dentry_operations(dentry); | ||
302 | unlock_kernel(); | 301 | unlock_kernel(); |
303 | d_add(dentry, result); | 302 | d_add(dentry, result); |
304 | return NULL; | 303 | return NULL; |
diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h index 2fee17d0d9ab..1c43dbea55e8 100644 --- a/fs/hpfs/hpfs_fn.h +++ b/fs/hpfs/hpfs_fn.h | |||
@@ -233,7 +233,7 @@ void hpfs_mark_4buffers_dirty(struct quad_buffer_head *); | |||
233 | 233 | ||
234 | /* dentry.c */ | 234 | /* dentry.c */ |
235 | 235 | ||
236 | void hpfs_set_dentry_operations(struct dentry *); | 236 | extern const struct dentry_operations hpfs_dentry_operations; |
237 | 237 | ||
238 | /* dir.c */ | 238 | /* dir.c */ |
239 | 239 | ||
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c index 49935ba78db8..b30426b1fc97 100644 --- a/fs/hpfs/super.c +++ b/fs/hpfs/super.c | |||
@@ -550,6 +550,7 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) | |||
550 | /* Fill superblock stuff */ | 550 | /* Fill superblock stuff */ |
551 | s->s_magic = HPFS_SUPER_MAGIC; | 551 | s->s_magic = HPFS_SUPER_MAGIC; |
552 | s->s_op = &hpfs_sops; | 552 | s->s_op = &hpfs_sops; |
553 | s->s_d_op = &hpfs_dentry_operations; | ||
553 | 554 | ||
554 | sbi->sb_root = superblock->root; | 555 | sbi->sb_root = superblock->root; |
555 | sbi->sb_fs_size = superblock->n_sectors; | 556 | sbi->sb_fs_size = superblock->n_sectors; |
@@ -651,7 +652,6 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) | |||
651 | iput(root); | 652 | iput(root); |
652 | goto bail0; | 653 | goto bail0; |
653 | } | 654 | } |
654 | hpfs_set_dentry_operations(s->s_root); | ||
655 | 655 | ||
656 | /* | 656 | /* |
657 | * find the root directory's . pointer & finish filling in the inode | 657 | * find the root directory's . pointer & finish filling in the inode |
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 844a7903c72f..a0f3833c0dbf 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c | |||
@@ -939,17 +939,18 @@ root_found: | |||
939 | goto out_iput; | 939 | goto out_iput; |
940 | } | 940 | } |
941 | 941 | ||
942 | /* get the root dentry */ | ||
943 | s->s_root = d_alloc_root(inode); | ||
944 | if (!(s->s_root)) | ||
945 | goto out_no_root; | ||
946 | |||
947 | table = 0; | 942 | table = 0; |
948 | if (joliet_level) | 943 | if (joliet_level) |
949 | table += 2; | 944 | table += 2; |
950 | if (opt.check == 'r') | 945 | if (opt.check == 'r') |
951 | table++; | 946 | table++; |
952 | d_set_d_op(s->s_root, &isofs_dentry_ops[table]); | 947 | |
948 | s->s_d_op = &isofs_dentry_ops[table]; | ||
949 | |||
950 | /* get the root dentry */ | ||
951 | s->s_root = d_alloc_root(inode); | ||
952 | if (!(s->s_root)) | ||
953 | goto out_no_root; | ||
953 | 954 | ||
954 | kfree(opt.iocharset); | 955 | kfree(opt.iocharset); |
955 | 956 | ||
diff --git a/fs/isofs/namei.c b/fs/isofs/namei.c index 679a849c3b27..4fb3e8074fd4 100644 --- a/fs/isofs/namei.c +++ b/fs/isofs/namei.c | |||
@@ -172,8 +172,6 @@ struct dentry *isofs_lookup(struct inode *dir, struct dentry *dentry, struct nam | |||
172 | struct inode *inode; | 172 | struct inode *inode; |
173 | struct page *page; | 173 | struct page *page; |
174 | 174 | ||
175 | d_set_d_op(dentry, dir->i_sb->s_root->d_op); | ||
176 | |||
177 | page = alloc_page(GFP_USER); | 175 | page = alloc_page(GFP_USER); |
178 | if (!page) | 176 | if (!page) |
179 | return ERR_PTR(-ENOMEM); | 177 | return ERR_PTR(-ENOMEM); |
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c index 846a3f314111..5b2e4c30a2a1 100644 --- a/fs/jbd/transaction.c +++ b/fs/jbd/transaction.c | |||
@@ -207,7 +207,7 @@ repeat_locked: | |||
207 | * the committing transaction. Really, we only need to give it | 207 | * the committing transaction. Really, we only need to give it |
208 | * committing_transaction->t_outstanding_credits plus "enough" for | 208 | * committing_transaction->t_outstanding_credits plus "enough" for |
209 | * the log control blocks. | 209 | * the log control blocks. |
210 | * Also, this test is inconsitent with the matching one in | 210 | * Also, this test is inconsistent with the matching one in |
211 | * journal_extend(). | 211 | * journal_extend(). |
212 | */ | 212 | */ |
213 | if (__log_space_left(journal) < jbd_space_needed(journal)) { | 213 | if (__log_space_left(journal) < jbd_space_needed(journal)) { |
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 394893242ae3..faad2bd787c7 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
@@ -251,7 +251,7 @@ repeat: | |||
251 | * the committing transaction. Really, we only need to give it | 251 | * the committing transaction. Really, we only need to give it |
252 | * committing_transaction->t_outstanding_credits plus "enough" for | 252 | * committing_transaction->t_outstanding_credits plus "enough" for |
253 | * the log control blocks. | 253 | * the log control blocks. |
254 | * Also, this test is inconsitent with the matching one in | 254 | * Also, this test is inconsistent with the matching one in |
255 | * jbd2_journal_extend(). | 255 | * jbd2_journal_extend(). |
256 | */ | 256 | */ |
257 | if (__jbd2_log_space_left(journal) < jbd_space_needed(journal)) { | 257 | if (__jbd2_log_space_left(journal) < jbd_space_needed(journal)) { |
diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index e1b8493b9aaa..278e3fb40b71 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c | |||
@@ -1120,16 +1120,13 @@ int lmLogOpen(struct super_block *sb) | |||
1120 | * file systems to log may have n-to-1 relationship; | 1120 | * file systems to log may have n-to-1 relationship; |
1121 | */ | 1121 | */ |
1122 | 1122 | ||
1123 | bdev = open_by_devnum(sbi->logdev, FMODE_READ|FMODE_WRITE); | 1123 | bdev = blkdev_get_by_dev(sbi->logdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL, |
1124 | log); | ||
1124 | if (IS_ERR(bdev)) { | 1125 | if (IS_ERR(bdev)) { |
1125 | rc = -PTR_ERR(bdev); | 1126 | rc = -PTR_ERR(bdev); |
1126 | goto free; | 1127 | goto free; |
1127 | } | 1128 | } |
1128 | 1129 | ||
1129 | if ((rc = bd_claim(bdev, log))) { | ||
1130 | goto close; | ||
1131 | } | ||
1132 | |||
1133 | log->bdev = bdev; | 1130 | log->bdev = bdev; |
1134 | memcpy(log->uuid, sbi->loguuid, sizeof(log->uuid)); | 1131 | memcpy(log->uuid, sbi->loguuid, sizeof(log->uuid)); |
1135 | 1132 | ||
@@ -1137,7 +1134,7 @@ int lmLogOpen(struct super_block *sb) | |||
1137 | * initialize log: | 1134 | * initialize log: |
1138 | */ | 1135 | */ |
1139 | if ((rc = lmLogInit(log))) | 1136 | if ((rc = lmLogInit(log))) |
1140 | goto unclaim; | 1137 | goto close; |
1141 | 1138 | ||
1142 | list_add(&log->journal_list, &jfs_external_logs); | 1139 | list_add(&log->journal_list, &jfs_external_logs); |
1143 | 1140 | ||
@@ -1163,11 +1160,8 @@ journal_found: | |||
1163 | list_del(&log->journal_list); | 1160 | list_del(&log->journal_list); |
1164 | lbmLogShutdown(log); | 1161 | lbmLogShutdown(log); |
1165 | 1162 | ||
1166 | unclaim: | ||
1167 | bd_release(bdev); | ||
1168 | |||
1169 | close: /* close external log device */ | 1163 | close: /* close external log device */ |
1170 | blkdev_put(bdev, FMODE_READ|FMODE_WRITE); | 1164 | blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); |
1171 | 1165 | ||
1172 | free: /* free log descriptor */ | 1166 | free: /* free log descriptor */ |
1173 | mutex_unlock(&jfs_log_mutex); | 1167 | mutex_unlock(&jfs_log_mutex); |
@@ -1512,8 +1506,7 @@ int lmLogClose(struct super_block *sb) | |||
1512 | bdev = log->bdev; | 1506 | bdev = log->bdev; |
1513 | rc = lmLogShutdown(log); | 1507 | rc = lmLogShutdown(log); |
1514 | 1508 | ||
1515 | bd_release(bdev); | 1509 | blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); |
1516 | blkdev_put(bdev, FMODE_READ|FMODE_WRITE); | ||
1517 | 1510 | ||
1518 | kfree(log); | 1511 | kfree(log); |
1519 | 1512 | ||
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 4414e3a42264..81ead850ddb6 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c | |||
@@ -1465,9 +1465,6 @@ static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry, struc | |||
1465 | 1465 | ||
1466 | jfs_info("jfs_lookup: name = %s", name); | 1466 | jfs_info("jfs_lookup: name = %s", name); |
1467 | 1467 | ||
1468 | if (JFS_SBI(dip->i_sb)->mntflag & JFS_OS2) | ||
1469 | d_set_d_op(dentry, &jfs_ci_dentry_operations); | ||
1470 | |||
1471 | if ((name[0] == '.') && (len == 1)) | 1468 | if ((name[0] == '.') && (len == 1)) |
1472 | inum = dip->i_ino; | 1469 | inum = dip->i_ino; |
1473 | else if (strcmp(name, "..") == 0) | 1470 | else if (strcmp(name, "..") == 0) |
@@ -1492,12 +1489,7 @@ static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry, struc | |||
1492 | return ERR_CAST(ip); | 1489 | return ERR_CAST(ip); |
1493 | } | 1490 | } |
1494 | 1491 | ||
1495 | dentry = d_splice_alias(ip, dentry); | 1492 | return d_splice_alias(ip, dentry); |
1496 | |||
1497 | if (dentry && (JFS_SBI(dip->i_sb)->mntflag & JFS_OS2)) | ||
1498 | d_set_d_op(dentry, &jfs_ci_dentry_operations); | ||
1499 | |||
1500 | return dentry; | ||
1501 | } | 1493 | } |
1502 | 1494 | ||
1503 | static struct inode *jfs_nfs_get_inode(struct super_block *sb, | 1495 | static struct inode *jfs_nfs_get_inode(struct super_block *sb, |
diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 3150d766e0d4..eeca48a031ab 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c | |||
@@ -515,6 +515,9 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) | |||
515 | 515 | ||
516 | sb->s_magic = JFS_SUPER_MAGIC; | 516 | sb->s_magic = JFS_SUPER_MAGIC; |
517 | 517 | ||
518 | if (sbi->mntflag & JFS_OS2) | ||
519 | sb->s_d_op = &jfs_ci_dentry_operations; | ||
520 | |||
518 | inode = jfs_iget(sb, ROOT_I); | 521 | inode = jfs_iget(sb, ROOT_I); |
519 | if (IS_ERR(inode)) { | 522 | if (IS_ERR(inode)) { |
520 | ret = PTR_ERR(inode); | 523 | ret = PTR_ERR(inode); |
@@ -524,9 +527,6 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) | |||
524 | if (!sb->s_root) | 527 | if (!sb->s_root) |
525 | goto out_no_root; | 528 | goto out_no_root; |
526 | 529 | ||
527 | if (sbi->mntflag & JFS_OS2) | ||
528 | d_set_d_op(sb->s_root, &jfs_ci_dentry_operations); | ||
529 | |||
530 | /* logical blocks are represented by 40 bits in pxd_t, etc. */ | 530 | /* logical blocks are represented by 40 bits in pxd_t, etc. */ |
531 | sb->s_maxbytes = ((u64) sb->s_blocksize) << 40; | 531 | sb->s_maxbytes = ((u64) sb->s_blocksize) << 40; |
532 | #if BITS_PER_LONG == 32 | 532 | #if BITS_PER_LONG == 32 |
diff --git a/fs/libfs.c b/fs/libfs.c index 889311e3d06b..c88eab55aec9 100644 --- a/fs/libfs.c +++ b/fs/libfs.c | |||
@@ -217,7 +217,8 @@ static const struct super_operations simple_super_operations = { | |||
217 | * will never be mountable) | 217 | * will never be mountable) |
218 | */ | 218 | */ |
219 | struct dentry *mount_pseudo(struct file_system_type *fs_type, char *name, | 219 | struct dentry *mount_pseudo(struct file_system_type *fs_type, char *name, |
220 | const struct super_operations *ops, unsigned long magic) | 220 | const struct super_operations *ops, |
221 | const struct dentry_operations *dops, unsigned long magic) | ||
221 | { | 222 | { |
222 | struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL); | 223 | struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL); |
223 | struct dentry *dentry; | 224 | struct dentry *dentry; |
@@ -254,6 +255,7 @@ struct dentry *mount_pseudo(struct file_system_type *fs_type, char *name, | |||
254 | dentry->d_parent = dentry; | 255 | dentry->d_parent = dentry; |
255 | d_instantiate(dentry, root); | 256 | d_instantiate(dentry, root); |
256 | s->s_root = dentry; | 257 | s->s_root = dentry; |
258 | s->s_d_op = dops; | ||
257 | s->s_flags |= MS_ACTIVE; | 259 | s->s_flags |= MS_ACTIVE; |
258 | return dget(s->s_root); | 260 | return dget(s->s_root); |
259 | 261 | ||
diff --git a/fs/logfs/dev_bdev.c b/fs/logfs/dev_bdev.c index 92ca6fbe09bd..723bc5bca09a 100644 --- a/fs/logfs/dev_bdev.c +++ b/fs/logfs/dev_bdev.c | |||
@@ -300,7 +300,7 @@ static int bdev_write_sb(struct super_block *sb, struct page *page) | |||
300 | 300 | ||
301 | static void bdev_put_device(struct logfs_super *s) | 301 | static void bdev_put_device(struct logfs_super *s) |
302 | { | 302 | { |
303 | close_bdev_exclusive(s->s_bdev, FMODE_READ|FMODE_WRITE); | 303 | blkdev_put(s->s_bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); |
304 | } | 304 | } |
305 | 305 | ||
306 | static int bdev_can_write_buf(struct super_block *sb, u64 ofs) | 306 | static int bdev_can_write_buf(struct super_block *sb, u64 ofs) |
@@ -325,13 +325,14 @@ int logfs_get_sb_bdev(struct logfs_super *p, struct file_system_type *type, | |||
325 | { | 325 | { |
326 | struct block_device *bdev; | 326 | struct block_device *bdev; |
327 | 327 | ||
328 | bdev = open_bdev_exclusive(devname, FMODE_READ|FMODE_WRITE, type); | 328 | bdev = blkdev_get_by_path(devname, FMODE_READ|FMODE_WRITE|FMODE_EXCL, |
329 | type); | ||
329 | if (IS_ERR(bdev)) | 330 | if (IS_ERR(bdev)) |
330 | return PTR_ERR(bdev); | 331 | return PTR_ERR(bdev); |
331 | 332 | ||
332 | if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) { | 333 | if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) { |
333 | int mtdnr = MINOR(bdev->bd_dev); | 334 | int mtdnr = MINOR(bdev->bd_dev); |
334 | close_bdev_exclusive(bdev, FMODE_READ|FMODE_WRITE); | 335 | blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); |
335 | return logfs_get_sb_mtd(p, mtdnr); | 336 | return logfs_get_sb_mtd(p, mtdnr); |
336 | } | 337 | } |
337 | 338 | ||
diff --git a/fs/minix/namei.c b/fs/minix/namei.c index 1b9e07728a9f..ce7337ddfdbf 100644 --- a/fs/minix/namei.c +++ b/fs/minix/namei.c | |||
@@ -23,8 +23,6 @@ static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry, st | |||
23 | struct inode * inode = NULL; | 23 | struct inode * inode = NULL; |
24 | ino_t ino; | 24 | ino_t ino; |
25 | 25 | ||
26 | d_set_d_op(dentry, dir->i_sb->s_root->d_op); | ||
27 | |||
28 | if (dentry->d_name.len > minix_sb(dir->i_sb)->s_namelen) | 26 | if (dentry->d_name.len > minix_sb(dir->i_sb)->s_namelen) |
29 | return ERR_PTR(-ENAMETOOLONG); | 27 | return ERR_PTR(-ENAMETOOLONG); |
30 | 28 | ||
diff --git a/fs/mpage.c b/fs/mpage.c index fd56ca2ea556..d78455a81ec9 100644 --- a/fs/mpage.c +++ b/fs/mpage.c | |||
@@ -40,7 +40,7 @@ | |||
40 | * status of that page is hard. See end_buffer_async_read() for the details. | 40 | * status of that page is hard. See end_buffer_async_read() for the details. |
41 | * There is no point in duplicating all that complexity. | 41 | * There is no point in duplicating all that complexity. |
42 | */ | 42 | */ |
43 | static void mpage_end_io_read(struct bio *bio, int err) | 43 | static void mpage_end_io(struct bio *bio, int err) |
44 | { | 44 | { |
45 | const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); | 45 | const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); |
46 | struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; | 46 | struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; |
@@ -50,44 +50,29 @@ static void mpage_end_io_read(struct bio *bio, int err) | |||
50 | 50 | ||
51 | if (--bvec >= bio->bi_io_vec) | 51 | if (--bvec >= bio->bi_io_vec) |
52 | prefetchw(&bvec->bv_page->flags); | 52 | prefetchw(&bvec->bv_page->flags); |
53 | 53 | if (bio_data_dir(bio) == READ) { | |
54 | if (uptodate) { | 54 | if (uptodate) { |
55 | SetPageUptodate(page); | 55 | SetPageUptodate(page); |
56 | } else { | 56 | } else { |
57 | ClearPageUptodate(page); | 57 | ClearPageUptodate(page); |
58 | SetPageError(page); | 58 | SetPageError(page); |
59 | } | 59 | } |
60 | unlock_page(page); | 60 | unlock_page(page); |
61 | } while (bvec >= bio->bi_io_vec); | 61 | } else { /* bio_data_dir(bio) == WRITE */ |
62 | bio_put(bio); | 62 | if (!uptodate) { |
63 | } | 63 | SetPageError(page); |
64 | 64 | if (page->mapping) | |
65 | static void mpage_end_io_write(struct bio *bio, int err) | 65 | set_bit(AS_EIO, &page->mapping->flags); |
66 | { | 66 | } |
67 | const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); | 67 | end_page_writeback(page); |
68 | struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; | ||
69 | |||
70 | do { | ||
71 | struct page *page = bvec->bv_page; | ||
72 | |||
73 | if (--bvec >= bio->bi_io_vec) | ||
74 | prefetchw(&bvec->bv_page->flags); | ||
75 | |||
76 | if (!uptodate){ | ||
77 | SetPageError(page); | ||
78 | if (page->mapping) | ||
79 | set_bit(AS_EIO, &page->mapping->flags); | ||
80 | } | 68 | } |
81 | end_page_writeback(page); | ||
82 | } while (bvec >= bio->bi_io_vec); | 69 | } while (bvec >= bio->bi_io_vec); |
83 | bio_put(bio); | 70 | bio_put(bio); |
84 | } | 71 | } |
85 | 72 | ||
86 | static struct bio *mpage_bio_submit(int rw, struct bio *bio) | 73 | static struct bio *mpage_bio_submit(int rw, struct bio *bio) |
87 | { | 74 | { |
88 | bio->bi_end_io = mpage_end_io_read; | 75 | bio->bi_end_io = mpage_end_io; |
89 | if (rw == WRITE) | ||
90 | bio->bi_end_io = mpage_end_io_write; | ||
91 | submit_bio(rw, bio); | 76 | submit_bio(rw, bio); |
92 | return NULL; | 77 | return NULL; |
93 | } | 78 | } |
diff --git a/fs/namei.c b/fs/namei.c index 24ece10470b6..86643302079e 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -479,6 +479,14 @@ static int nameidata_dentry_drop_rcu(struct nameidata *nd, struct dentry *dentry | |||
479 | struct fs_struct *fs = current->fs; | 479 | struct fs_struct *fs = current->fs; |
480 | struct dentry *parent = nd->path.dentry; | 480 | struct dentry *parent = nd->path.dentry; |
481 | 481 | ||
482 | /* | ||
483 | * It can be possible to revalidate the dentry that we started | ||
484 | * the path walk with. force_reval_path may also revalidate the | ||
485 | * dentry already committed to the nameidata. | ||
486 | */ | ||
487 | if (unlikely(parent == dentry)) | ||
488 | return nameidata_drop_rcu(nd); | ||
489 | |||
482 | BUG_ON(!(nd->flags & LOOKUP_RCU)); | 490 | BUG_ON(!(nd->flags & LOOKUP_RCU)); |
483 | if (nd->root.mnt) { | 491 | if (nd->root.mnt) { |
484 | spin_lock(&fs->lock); | 492 | spin_lock(&fs->lock); |
@@ -583,6 +591,13 @@ void release_open_intent(struct nameidata *nd) | |||
583 | fput(nd->intent.open.file); | 591 | fput(nd->intent.open.file); |
584 | } | 592 | } |
585 | 593 | ||
594 | /* | ||
595 | * Call d_revalidate and handle filesystems that request rcu-walk | ||
596 | * to be dropped. This may be called and return in rcu-walk mode, | ||
597 | * regardless of success or error. If -ECHILD is returned, the caller | ||
598 | * must return -ECHILD back up the path walk stack so path walk may | ||
599 | * be restarted in ref-walk mode. | ||
600 | */ | ||
586 | static int d_revalidate(struct dentry *dentry, struct nameidata *nd) | 601 | static int d_revalidate(struct dentry *dentry, struct nameidata *nd) |
587 | { | 602 | { |
588 | int status; | 603 | int status; |
@@ -673,6 +688,9 @@ force_reval_path(struct path *path, struct nameidata *nd) | |||
673 | return 0; | 688 | return 0; |
674 | 689 | ||
675 | if (!status) { | 690 | if (!status) { |
691 | /* Don't d_invalidate in rcu-walk mode */ | ||
692 | if (nameidata_drop_rcu(nd)) | ||
693 | return -ECHILD; | ||
676 | d_invalidate(dentry); | 694 | d_invalidate(dentry); |
677 | status = -ESTALE; | 695 | status = -ESTALE; |
678 | } | 696 | } |
@@ -1950,8 +1968,9 @@ int may_open(struct path *path, int acc_mode, int flag) | |||
1950 | return break_lease(inode, flag); | 1968 | return break_lease(inode, flag); |
1951 | } | 1969 | } |
1952 | 1970 | ||
1953 | static int handle_truncate(struct path *path) | 1971 | static int handle_truncate(struct file *filp) |
1954 | { | 1972 | { |
1973 | struct path *path = &filp->f_path; | ||
1955 | struct inode *inode = path->dentry->d_inode; | 1974 | struct inode *inode = path->dentry->d_inode; |
1956 | int error = get_write_access(inode); | 1975 | int error = get_write_access(inode); |
1957 | if (error) | 1976 | if (error) |
@@ -1965,7 +1984,7 @@ static int handle_truncate(struct path *path) | |||
1965 | if (!error) { | 1984 | if (!error) { |
1966 | error = do_truncate(path->dentry, 0, | 1985 | error = do_truncate(path->dentry, 0, |
1967 | ATTR_MTIME|ATTR_CTIME|ATTR_OPEN, | 1986 | ATTR_MTIME|ATTR_CTIME|ATTR_OPEN, |
1968 | NULL); | 1987 | filp); |
1969 | } | 1988 | } |
1970 | put_write_access(inode); | 1989 | put_write_access(inode); |
1971 | return error; | 1990 | return error; |
@@ -2063,7 +2082,7 @@ static struct file *finish_open(struct nameidata *nd, | |||
2063 | } | 2082 | } |
2064 | if (!IS_ERR(filp)) { | 2083 | if (!IS_ERR(filp)) { |
2065 | if (will_truncate) { | 2084 | if (will_truncate) { |
2066 | error = handle_truncate(&nd->path); | 2085 | error = handle_truncate(filp); |
2067 | if (error) { | 2086 | if (error) { |
2068 | fput(filp); | 2087 | fput(filp); |
2069 | filp = ERR_PTR(error); | 2088 | filp = ERR_PTR(error); |
@@ -2104,11 +2123,13 @@ static struct file *do_last(struct nameidata *nd, struct path *path, | |||
2104 | dir = nd->path.dentry; | 2123 | dir = nd->path.dentry; |
2105 | case LAST_DOT: | 2124 | case LAST_DOT: |
2106 | if (need_reval_dot(dir)) { | 2125 | if (need_reval_dot(dir)) { |
2107 | error = d_revalidate(nd->path.dentry, nd); | 2126 | int status = d_revalidate(nd->path.dentry, nd); |
2108 | if (!error) | 2127 | if (!status) |
2109 | error = -ESTALE; | 2128 | status = -ESTALE; |
2110 | if (error < 0) | 2129 | if (status < 0) { |
2130 | error = status; | ||
2111 | goto exit; | 2131 | goto exit; |
2132 | } | ||
2112 | } | 2133 | } |
2113 | /* fallthrough */ | 2134 | /* fallthrough */ |
2114 | case LAST_ROOT: | 2135 | case LAST_ROOT: |
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index 28f136d4aaec..f6946bb5cb55 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c | |||
@@ -21,9 +21,7 @@ | |||
21 | #include <asm/uaccess.h> | 21 | #include <asm/uaccess.h> |
22 | #include <asm/byteorder.h> | 22 | #include <asm/byteorder.h> |
23 | 23 | ||
24 | #include <linux/ncp_fs.h> | 24 | #include "ncp_fs.h" |
25 | |||
26 | #include "ncplib_kernel.h" | ||
27 | 25 | ||
28 | static void ncp_read_volume_list(struct file *, void *, filldir_t, | 26 | static void ncp_read_volume_list(struct file *, void *, filldir_t, |
29 | struct ncp_cache_control *); | 27 | struct ncp_cache_control *); |
@@ -82,7 +80,7 @@ static int ncp_compare_dentry(const struct dentry *, const struct inode *, | |||
82 | unsigned int, const char *, const struct qstr *); | 80 | unsigned int, const char *, const struct qstr *); |
83 | static int ncp_delete_dentry(const struct dentry *); | 81 | static int ncp_delete_dentry(const struct dentry *); |
84 | 82 | ||
85 | static const struct dentry_operations ncp_dentry_operations = | 83 | const struct dentry_operations ncp_dentry_operations = |
86 | { | 84 | { |
87 | .d_revalidate = ncp_lookup_validate, | 85 | .d_revalidate = ncp_lookup_validate, |
88 | .d_hash = ncp_hash_dentry, | 86 | .d_hash = ncp_hash_dentry, |
@@ -90,14 +88,6 @@ static const struct dentry_operations ncp_dentry_operations = | |||
90 | .d_delete = ncp_delete_dentry, | 88 | .d_delete = ncp_delete_dentry, |
91 | }; | 89 | }; |
92 | 90 | ||
93 | const struct dentry_operations ncp_root_dentry_operations = | ||
94 | { | ||
95 | .d_hash = ncp_hash_dentry, | ||
96 | .d_compare = ncp_compare_dentry, | ||
97 | .d_delete = ncp_delete_dentry, | ||
98 | }; | ||
99 | |||
100 | |||
101 | #define ncp_namespace(i) (NCP_SERVER(i)->name_space[NCP_FINFO(i)->volNumber]) | 91 | #define ncp_namespace(i) (NCP_SERVER(i)->name_space[NCP_FINFO(i)->volNumber]) |
102 | 92 | ||
103 | static inline int ncp_preserve_entry_case(struct inode *i, __u32 nscreator) | 93 | static inline int ncp_preserve_entry_case(struct inode *i, __u32 nscreator) |
@@ -309,6 +299,9 @@ ncp_lookup_validate(struct dentry *dentry, struct nameidata *nd) | |||
309 | int res, val = 0, len; | 299 | int res, val = 0, len; |
310 | __u8 __name[NCP_MAXPATHLEN + 1]; | 300 | __u8 __name[NCP_MAXPATHLEN + 1]; |
311 | 301 | ||
302 | if (dentry == dentry->d_sb->s_root) | ||
303 | return 1; | ||
304 | |||
312 | if (nd->flags & LOOKUP_RCU) | 305 | if (nd->flags & LOOKUP_RCU) |
313 | return -ECHILD; | 306 | return -ECHILD; |
314 | 307 | ||
@@ -637,7 +630,6 @@ ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir, | |||
637 | entry->ino = iunique(dir->i_sb, 2); | 630 | entry->ino = iunique(dir->i_sb, 2); |
638 | inode = ncp_iget(dir->i_sb, entry); | 631 | inode = ncp_iget(dir->i_sb, entry); |
639 | if (inode) { | 632 | if (inode) { |
640 | d_set_d_op(newdent, &ncp_dentry_operations); | ||
641 | d_instantiate(newdent, inode); | 633 | d_instantiate(newdent, inode); |
642 | if (!hashed) | 634 | if (!hashed) |
643 | d_rehash(newdent); | 635 | d_rehash(newdent); |
@@ -893,7 +885,6 @@ static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry, struc | |||
893 | if (inode) { | 885 | if (inode) { |
894 | ncp_new_dentry(dentry); | 886 | ncp_new_dentry(dentry); |
895 | add_entry: | 887 | add_entry: |
896 | d_set_d_op(dentry, &ncp_dentry_operations); | ||
897 | d_add(dentry, inode); | 888 | d_add(dentry, inode); |
898 | error = 0; | 889 | error = 0; |
899 | } | 890 | } |
diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c index cb50aaf981df..0ed65e0c3dfe 100644 --- a/fs/ncpfs/file.c +++ b/fs/ncpfs/file.c | |||
@@ -18,8 +18,7 @@ | |||
18 | #include <linux/vmalloc.h> | 18 | #include <linux/vmalloc.h> |
19 | #include <linux/sched.h> | 19 | #include <linux/sched.h> |
20 | 20 | ||
21 | #include <linux/ncp_fs.h> | 21 | #include "ncp_fs.h" |
22 | #include "ncplib_kernel.h" | ||
23 | 22 | ||
24 | static int ncp_fsync(struct file *file, int datasync) | 23 | static int ncp_fsync(struct file *file, int datasync) |
25 | { | 24 | { |
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index 9b39a5dd4131..00a1d1c3d3a4 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c | |||
@@ -31,11 +31,9 @@ | |||
31 | #include <linux/seq_file.h> | 31 | #include <linux/seq_file.h> |
32 | #include <linux/namei.h> | 32 | #include <linux/namei.h> |
33 | 33 | ||
34 | #include <linux/ncp_fs.h> | ||
35 | |||
36 | #include <net/sock.h> | 34 | #include <net/sock.h> |
37 | 35 | ||
38 | #include "ncplib_kernel.h" | 36 | #include "ncp_fs.h" |
39 | #include "getopt.h" | 37 | #include "getopt.h" |
40 | 38 | ||
41 | #define NCP_DEFAULT_FILE_MODE 0600 | 39 | #define NCP_DEFAULT_FILE_MODE 0600 |
@@ -544,6 +542,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
544 | sb->s_blocksize_bits = 10; | 542 | sb->s_blocksize_bits = 10; |
545 | sb->s_magic = NCP_SUPER_MAGIC; | 543 | sb->s_magic = NCP_SUPER_MAGIC; |
546 | sb->s_op = &ncp_sops; | 544 | sb->s_op = &ncp_sops; |
545 | sb->s_d_op = &ncp_dentry_operations; | ||
547 | sb->s_bdi = &server->bdi; | 546 | sb->s_bdi = &server->bdi; |
548 | 547 | ||
549 | server = NCP_SBP(sb); | 548 | server = NCP_SBP(sb); |
@@ -723,7 +722,6 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
723 | sb->s_root = d_alloc_root(root_inode); | 722 | sb->s_root = d_alloc_root(root_inode); |
724 | if (!sb->s_root) | 723 | if (!sb->s_root) |
725 | goto out_no_root; | 724 | goto out_no_root; |
726 | d_set_d_op(sb->s_root, &ncp_root_dentry_operations); | ||
727 | return 0; | 725 | return 0; |
728 | 726 | ||
729 | out_no_root: | 727 | out_no_root: |
diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c index d40a547e3377..790e92a9ec63 100644 --- a/fs/ncpfs/ioctl.c +++ b/fs/ncpfs/ioctl.c | |||
@@ -20,11 +20,9 @@ | |||
20 | #include <linux/vmalloc.h> | 20 | #include <linux/vmalloc.h> |
21 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
22 | 22 | ||
23 | #include <linux/ncp_fs.h> | ||
24 | |||
25 | #include <asm/uaccess.h> | 23 | #include <asm/uaccess.h> |
26 | 24 | ||
27 | #include "ncplib_kernel.h" | 25 | #include "ncp_fs.h" |
28 | 26 | ||
29 | /* maximum limit for ncp_objectname_ioctl */ | 27 | /* maximum limit for ncp_objectname_ioctl */ |
30 | #define NCP_OBJECT_NAME_MAX_LEN 4096 | 28 | #define NCP_OBJECT_NAME_MAX_LEN 4096 |
diff --git a/fs/ncpfs/mmap.c b/fs/ncpfs/mmap.c index 56f5b3a0e1ee..a7c07b44b100 100644 --- a/fs/ncpfs/mmap.c +++ b/fs/ncpfs/mmap.c | |||
@@ -16,12 +16,12 @@ | |||
16 | #include <linux/mman.h> | 16 | #include <linux/mman.h> |
17 | #include <linux/string.h> | 17 | #include <linux/string.h> |
18 | #include <linux/fcntl.h> | 18 | #include <linux/fcntl.h> |
19 | #include <linux/ncp_fs.h> | ||
20 | 19 | ||
21 | #include "ncplib_kernel.h" | ||
22 | #include <asm/uaccess.h> | 20 | #include <asm/uaccess.h> |
23 | #include <asm/system.h> | 21 | #include <asm/system.h> |
24 | 22 | ||
23 | #include "ncp_fs.h" | ||
24 | |||
25 | /* | 25 | /* |
26 | * Fill in the supplied page for mmap | 26 | * Fill in the supplied page for mmap |
27 | * XXX: how are we excluding truncate/invalidate here? Maybe need to lock | 27 | * XXX: how are we excluding truncate/invalidate here? Maybe need to lock |
diff --git a/fs/ncpfs/ncp_fs.h b/fs/ncpfs/ncp_fs.h new file mode 100644 index 000000000000..31831afe1c3b --- /dev/null +++ b/fs/ncpfs/ncp_fs.h | |||
@@ -0,0 +1,98 @@ | |||
1 | #include <linux/ncp_fs.h> | ||
2 | #include "ncp_fs_i.h" | ||
3 | #include "ncp_fs_sb.h" | ||
4 | |||
5 | /* define because it is easy to change PRINTK to {*}PRINTK */ | ||
6 | #define PRINTK(format, args...) printk(KERN_DEBUG format , ## args) | ||
7 | |||
8 | #undef NCPFS_PARANOIA | ||
9 | #ifdef NCPFS_PARANOIA | ||
10 | #define PPRINTK(format, args...) PRINTK(format , ## args) | ||
11 | #else | ||
12 | #define PPRINTK(format, args...) | ||
13 | #endif | ||
14 | |||
15 | #ifndef DEBUG_NCP | ||
16 | #define DEBUG_NCP 0 | ||
17 | #endif | ||
18 | #if DEBUG_NCP > 0 | ||
19 | #define DPRINTK(format, args...) PRINTK(format , ## args) | ||
20 | #else | ||
21 | #define DPRINTK(format, args...) | ||
22 | #endif | ||
23 | #if DEBUG_NCP > 1 | ||
24 | #define DDPRINTK(format, args...) PRINTK(format , ## args) | ||
25 | #else | ||
26 | #define DDPRINTK(format, args...) | ||
27 | #endif | ||
28 | |||
29 | #define NCP_MAX_RPC_TIMEOUT (6*HZ) | ||
30 | |||
31 | |||
32 | struct ncp_entry_info { | ||
33 | struct nw_info_struct i; | ||
34 | ino_t ino; | ||
35 | int opened; | ||
36 | int access; | ||
37 | unsigned int volume; | ||
38 | __u8 file_handle[6]; | ||
39 | }; | ||
40 | |||
41 | static inline struct ncp_server *NCP_SBP(const struct super_block *sb) | ||
42 | { | ||
43 | return sb->s_fs_info; | ||
44 | } | ||
45 | |||
46 | #define NCP_SERVER(inode) NCP_SBP((inode)->i_sb) | ||
47 | static inline struct ncp_inode_info *NCP_FINFO(const struct inode *inode) | ||
48 | { | ||
49 | return container_of(inode, struct ncp_inode_info, vfs_inode); | ||
50 | } | ||
51 | |||
52 | /* linux/fs/ncpfs/inode.c */ | ||
53 | int ncp_notify_change(struct dentry *, struct iattr *); | ||
54 | struct inode *ncp_iget(struct super_block *, struct ncp_entry_info *); | ||
55 | void ncp_update_inode(struct inode *, struct ncp_entry_info *); | ||
56 | void ncp_update_inode2(struct inode *, struct ncp_entry_info *); | ||
57 | |||
58 | /* linux/fs/ncpfs/dir.c */ | ||
59 | extern const struct inode_operations ncp_dir_inode_operations; | ||
60 | extern const struct file_operations ncp_dir_operations; | ||
61 | extern const struct dentry_operations ncp_dentry_operations; | ||
62 | int ncp_conn_logged_in(struct super_block *); | ||
63 | int ncp_date_dos2unix(__le16 time, __le16 date); | ||
64 | void ncp_date_unix2dos(int unix_date, __le16 * time, __le16 * date); | ||
65 | |||
66 | /* linux/fs/ncpfs/ioctl.c */ | ||
67 | long ncp_ioctl(struct file *, unsigned int, unsigned long); | ||
68 | long ncp_compat_ioctl(struct file *, unsigned int, unsigned long); | ||
69 | |||
70 | /* linux/fs/ncpfs/sock.c */ | ||
71 | int ncp_request2(struct ncp_server *server, int function, | ||
72 | void* reply, int max_reply_size); | ||
73 | static inline int ncp_request(struct ncp_server *server, int function) { | ||
74 | return ncp_request2(server, function, server->packet, server->packet_size); | ||
75 | } | ||
76 | int ncp_connect(struct ncp_server *server); | ||
77 | int ncp_disconnect(struct ncp_server *server); | ||
78 | void ncp_lock_server(struct ncp_server *server); | ||
79 | void ncp_unlock_server(struct ncp_server *server); | ||
80 | |||
81 | /* linux/fs/ncpfs/symlink.c */ | ||
82 | #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS) | ||
83 | extern const struct address_space_operations ncp_symlink_aops; | ||
84 | int ncp_symlink(struct inode*, struct dentry*, const char*); | ||
85 | #endif | ||
86 | |||
87 | /* linux/fs/ncpfs/file.c */ | ||
88 | extern const struct inode_operations ncp_file_inode_operations; | ||
89 | extern const struct file_operations ncp_file_operations; | ||
90 | int ncp_make_open(struct inode *, int); | ||
91 | |||
92 | /* linux/fs/ncpfs/mmap.c */ | ||
93 | int ncp_mmap(struct file *, struct vm_area_struct *); | ||
94 | |||
95 | /* linux/fs/ncpfs/ncplib_kernel.c */ | ||
96 | int ncp_make_closed(struct inode *); | ||
97 | |||
98 | #include "ncplib_kernel.h" | ||
diff --git a/fs/ncpfs/ncp_fs_i.h b/fs/ncpfs/ncp_fs_i.h new file mode 100644 index 000000000000..4b0bec477846 --- /dev/null +++ b/fs/ncpfs/ncp_fs_i.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /* | ||
2 | * ncp_fs_i.h | ||
3 | * | ||
4 | * Copyright (C) 1995 Volker Lendecke | ||
5 | * | ||
6 | */ | ||
7 | |||
8 | #ifndef _LINUX_NCP_FS_I | ||
9 | #define _LINUX_NCP_FS_I | ||
10 | |||
11 | /* | ||
12 | * This is the ncpfs part of the inode structure. This must contain | ||
13 | * all the information we need to work with an inode after creation. | ||
14 | */ | ||
15 | struct ncp_inode_info { | ||
16 | __le32 dirEntNum; | ||
17 | __le32 DosDirNum; | ||
18 | __u8 volNumber; | ||
19 | __le32 nwattr; | ||
20 | struct mutex open_mutex; | ||
21 | atomic_t opened; | ||
22 | int access; | ||
23 | int flags; | ||
24 | #define NCPI_KLUDGE_SYMLINK 0x0001 | ||
25 | __u8 file_handle[6]; | ||
26 | struct inode vfs_inode; | ||
27 | }; | ||
28 | |||
29 | #endif /* _LINUX_NCP_FS_I */ | ||
diff --git a/fs/ncpfs/ncp_fs_sb.h b/fs/ncpfs/ncp_fs_sb.h new file mode 100644 index 000000000000..4af803f13516 --- /dev/null +++ b/fs/ncpfs/ncp_fs_sb.h | |||
@@ -0,0 +1,176 @@ | |||
1 | /* | ||
2 | * ncp_fs_sb.h | ||
3 | * | ||
4 | * Copyright (C) 1995, 1996 by Volker Lendecke | ||
5 | * | ||
6 | */ | ||
7 | |||
8 | #ifndef _NCP_FS_SB | ||
9 | #define _NCP_FS_SB | ||
10 | |||
11 | #include <linux/types.h> | ||
12 | #include <linux/ncp_mount.h> | ||
13 | #include <linux/net.h> | ||
14 | #include <linux/mutex.h> | ||
15 | #include <linux/backing-dev.h> | ||
16 | #include <linux/workqueue.h> | ||
17 | |||
18 | #define NCP_DEFAULT_OPTIONS 0 /* 2 for packet signatures */ | ||
19 | |||
20 | struct sock; | ||
21 | |||
22 | struct ncp_mount_data_kernel { | ||
23 | unsigned long flags; /* NCP_MOUNT_* flags */ | ||
24 | unsigned int int_flags; /* internal flags */ | ||
25 | #define NCP_IMOUNT_LOGGEDIN_POSSIBLE 0x0001 | ||
26 | __kernel_uid32_t mounted_uid; /* Who may umount() this filesystem? */ | ||
27 | struct pid *wdog_pid; /* Who cares for our watchdog packets? */ | ||
28 | unsigned int ncp_fd; /* The socket to the ncp port */ | ||
29 | unsigned int time_out; /* How long should I wait after | ||
30 | sending a NCP request? */ | ||
31 | unsigned int retry_count; /* And how often should I retry? */ | ||
32 | unsigned char mounted_vol[NCP_VOLNAME_LEN + 1]; | ||
33 | __kernel_uid32_t uid; | ||
34 | __kernel_gid32_t gid; | ||
35 | __kernel_mode_t file_mode; | ||
36 | __kernel_mode_t dir_mode; | ||
37 | int info_fd; | ||
38 | }; | ||
39 | |||
40 | struct ncp_server { | ||
41 | |||
42 | struct ncp_mount_data_kernel m; /* Nearly all of the mount data is of | ||
43 | interest for us later, so we store | ||
44 | it completely. */ | ||
45 | |||
46 | __u8 name_space[NCP_NUMBER_OF_VOLUMES + 2]; | ||
47 | |||
48 | struct file *ncp_filp; /* File pointer to ncp socket */ | ||
49 | struct socket *ncp_sock;/* ncp socket */ | ||
50 | struct file *info_filp; | ||
51 | struct socket *info_sock; | ||
52 | |||
53 | u8 sequence; | ||
54 | u8 task; | ||
55 | u16 connection; /* Remote connection number */ | ||
56 | |||
57 | u8 completion; /* Status message from server */ | ||
58 | u8 conn_status; /* Bit 4 = 1 ==> Server going down, no | ||
59 | requests allowed anymore. | ||
60 | Bit 0 = 1 ==> Server is down. */ | ||
61 | |||
62 | int buffer_size; /* Negotiated bufsize */ | ||
63 | |||
64 | int reply_size; /* Size of last reply */ | ||
65 | |||
66 | int packet_size; | ||
67 | unsigned char *packet; /* Here we prepare requests and | ||
68 | receive replies */ | ||
69 | unsigned char *txbuf; /* Storage for current request */ | ||
70 | unsigned char *rxbuf; /* Storage for reply to current request */ | ||
71 | |||
72 | int lock; /* To prevent mismatch in protocols. */ | ||
73 | struct mutex mutex; | ||
74 | |||
75 | int current_size; /* for packet preparation */ | ||
76 | int has_subfunction; | ||
77 | int ncp_reply_size; | ||
78 | |||
79 | int root_setuped; | ||
80 | struct mutex root_setup_lock; | ||
81 | |||
82 | /* info for packet signing */ | ||
83 | int sign_wanted; /* 1=Server needs signed packets */ | ||
84 | int sign_active; /* 0=don't do signing, 1=do */ | ||
85 | char sign_root[8]; /* generated from password and encr. key */ | ||
86 | char sign_last[16]; | ||
87 | |||
88 | /* Authentication info: NDS or BINDERY, username */ | ||
89 | struct { | ||
90 | int auth_type; | ||
91 | size_t object_name_len; | ||
92 | void* object_name; | ||
93 | int object_type; | ||
94 | } auth; | ||
95 | /* Password info */ | ||
96 | struct { | ||
97 | size_t len; | ||
98 | void* data; | ||
99 | } priv; | ||
100 | struct rw_semaphore auth_rwsem; | ||
101 | |||
102 | /* nls info: codepage for volume and charset for I/O */ | ||
103 | struct nls_table *nls_vol; | ||
104 | struct nls_table *nls_io; | ||
105 | |||
106 | /* maximum age in jiffies */ | ||
107 | atomic_t dentry_ttl; | ||
108 | |||
109 | /* miscellaneous */ | ||
110 | unsigned int flags; | ||
111 | |||
112 | spinlock_t requests_lock; /* Lock accesses to tx.requests, tx.creq and rcv.creq when STREAM mode */ | ||
113 | |||
114 | void (*data_ready)(struct sock* sk, int len); | ||
115 | void (*error_report)(struct sock* sk); | ||
116 | void (*write_space)(struct sock* sk); /* STREAM mode only */ | ||
117 | struct { | ||
118 | struct work_struct tq; /* STREAM/DGRAM: data/error ready */ | ||
119 | struct ncp_request_reply* creq; /* STREAM/DGRAM: awaiting reply from this request */ | ||
120 | struct mutex creq_mutex; /* DGRAM only: lock accesses to rcv.creq */ | ||
121 | |||
122 | unsigned int state; /* STREAM only: receiver state */ | ||
123 | struct { | ||
124 | __u32 magic __packed; | ||
125 | __u32 len __packed; | ||
126 | __u16 type __packed; | ||
127 | __u16 p1 __packed; | ||
128 | __u16 p2 __packed; | ||
129 | __u16 p3 __packed; | ||
130 | __u16 type2 __packed; | ||
131 | } buf; /* STREAM only: temporary buffer */ | ||
132 | unsigned char* ptr; /* STREAM only: pointer to data */ | ||
133 | size_t len; /* STREAM only: length of data to receive */ | ||
134 | } rcv; | ||
135 | struct { | ||
136 | struct list_head requests; /* STREAM only: queued requests */ | ||
137 | struct work_struct tq; /* STREAM only: transmitter ready */ | ||
138 | struct ncp_request_reply* creq; /* STREAM only: currently transmitted entry */ | ||
139 | } tx; | ||
140 | struct timer_list timeout_tm; /* DGRAM only: timeout timer */ | ||
141 | struct work_struct timeout_tq; /* DGRAM only: associated queue, we run timers from process context */ | ||
142 | int timeout_last; /* DGRAM only: current timeout length */ | ||
143 | int timeout_retries; /* DGRAM only: retries left */ | ||
144 | struct { | ||
145 | size_t len; | ||
146 | __u8 data[128]; | ||
147 | } unexpected_packet; | ||
148 | struct backing_dev_info bdi; | ||
149 | }; | ||
150 | |||
151 | extern void ncp_tcp_rcv_proc(struct work_struct *work); | ||
152 | extern void ncp_tcp_tx_proc(struct work_struct *work); | ||
153 | extern void ncpdgram_rcv_proc(struct work_struct *work); | ||
154 | extern void ncpdgram_timeout_proc(struct work_struct *work); | ||
155 | extern void ncpdgram_timeout_call(unsigned long server); | ||
156 | extern void ncp_tcp_data_ready(struct sock* sk, int len); | ||
157 | extern void ncp_tcp_write_space(struct sock* sk); | ||
158 | extern void ncp_tcp_error_report(struct sock* sk); | ||
159 | |||
160 | #define NCP_FLAG_UTF8 1 | ||
161 | |||
162 | #define NCP_CLR_FLAG(server, flag) ((server)->flags &= ~(flag)) | ||
163 | #define NCP_SET_FLAG(server, flag) ((server)->flags |= (flag)) | ||
164 | #define NCP_IS_FLAG(server, flag) ((server)->flags & (flag)) | ||
165 | |||
166 | static inline int ncp_conn_valid(struct ncp_server *server) | ||
167 | { | ||
168 | return ((server->conn_status & 0x11) == 0); | ||
169 | } | ||
170 | |||
171 | static inline void ncp_invalidate_conn(struct ncp_server *server) | ||
172 | { | ||
173 | server->conn_status |= 0x01; | ||
174 | } | ||
175 | |||
176 | #endif | ||
diff --git a/fs/ncpfs/ncplib_kernel.c b/fs/ncpfs/ncplib_kernel.c index a95615a0b6ac..981a95617fc9 100644 --- a/fs/ncpfs/ncplib_kernel.c +++ b/fs/ncpfs/ncplib_kernel.c | |||
@@ -11,7 +11,7 @@ | |||
11 | 11 | ||
12 | 12 | ||
13 | 13 | ||
14 | #include "ncplib_kernel.h" | 14 | #include "ncp_fs.h" |
15 | 15 | ||
16 | static inline void assert_server_locked(struct ncp_server *server) | 16 | static inline void assert_server_locked(struct ncp_server *server) |
17 | { | 17 | { |
diff --git a/fs/ncpfs/ncplib_kernel.h b/fs/ncpfs/ncplib_kernel.h index 1220df75ff22..09881e6aa5ad 100644 --- a/fs/ncpfs/ncplib_kernel.h +++ b/fs/ncpfs/ncplib_kernel.h | |||
@@ -32,8 +32,6 @@ | |||
32 | #include <linux/ctype.h> | 32 | #include <linux/ctype.h> |
33 | #endif /* CONFIG_NCPFS_NLS */ | 33 | #endif /* CONFIG_NCPFS_NLS */ |
34 | 34 | ||
35 | #include <linux/ncp_fs.h> | ||
36 | |||
37 | #define NCP_MIN_SYMLINK_SIZE 8 | 35 | #define NCP_MIN_SYMLINK_SIZE 8 |
38 | #define NCP_MAX_SYMLINK_SIZE 512 | 36 | #define NCP_MAX_SYMLINK_SIZE 512 |
39 | 37 | ||
diff --git a/fs/ncpfs/ncpsign_kernel.c b/fs/ncpfs/ncpsign_kernel.c index d8b2d7e6910b..08907599dcd2 100644 --- a/fs/ncpfs/ncpsign_kernel.c +++ b/fs/ncpfs/ncpsign_kernel.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/string.h> | 11 | #include <linux/string.h> |
12 | #include <linux/ncp.h> | 12 | #include <linux/ncp.h> |
13 | #include <linux/bitops.h> | 13 | #include <linux/bitops.h> |
14 | #include "ncp_fs.h" | ||
14 | #include "ncpsign_kernel.h" | 15 | #include "ncpsign_kernel.h" |
15 | 16 | ||
16 | /* i386: 32-bit, little endian, handles mis-alignment */ | 17 | /* i386: 32-bit, little endian, handles mis-alignment */ |
diff --git a/fs/ncpfs/ncpsign_kernel.h b/fs/ncpfs/ncpsign_kernel.h index 6451a68381cc..d9a1438bb1f6 100644 --- a/fs/ncpfs/ncpsign_kernel.h +++ b/fs/ncpfs/ncpsign_kernel.h | |||
@@ -8,8 +8,6 @@ | |||
8 | #ifndef _NCPSIGN_KERNEL_H | 8 | #ifndef _NCPSIGN_KERNEL_H |
9 | #define _NCPSIGN_KERNEL_H | 9 | #define _NCPSIGN_KERNEL_H |
10 | 10 | ||
11 | #include <linux/ncp_fs.h> | ||
12 | |||
13 | #ifdef CONFIG_NCPFS_PACKET_SIGNING | 11 | #ifdef CONFIG_NCPFS_PACKET_SIGNING |
14 | void __sign_packet(struct ncp_server *server, const char *data, size_t size, __u32 totalsize, void *sign_buff); | 12 | void __sign_packet(struct ncp_server *server, const char *data, size_t size, __u32 totalsize, void *sign_buff); |
15 | int sign_verify_reply(struct ncp_server *server, const char *data, size_t size, __u32 totalsize, const void *sign_buff); | 13 | int sign_verify_reply(struct ncp_server *server, const char *data, size_t size, __u32 totalsize, const void *sign_buff); |
diff --git a/fs/ncpfs/sock.c b/fs/ncpfs/sock.c index 668bd267346e..3a1587222c8a 100644 --- a/fs/ncpfs/sock.c +++ b/fs/ncpfs/sock.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #include <linux/poll.h> | 28 | #include <linux/poll.h> |
29 | #include <linux/file.h> | 29 | #include <linux/file.h> |
30 | 30 | ||
31 | #include <linux/ncp_fs.h> | 31 | #include "ncp_fs.h" |
32 | 32 | ||
33 | #include "ncpsign_kernel.h" | 33 | #include "ncpsign_kernel.h" |
34 | 34 | ||
diff --git a/fs/ncpfs/symlink.c b/fs/ncpfs/symlink.c index c634fd17b337..661f861d80c6 100644 --- a/fs/ncpfs/symlink.c +++ b/fs/ncpfs/symlink.c | |||
@@ -25,13 +25,11 @@ | |||
25 | 25 | ||
26 | #include <linux/errno.h> | 26 | #include <linux/errno.h> |
27 | #include <linux/fs.h> | 27 | #include <linux/fs.h> |
28 | #include <linux/ncp_fs.h> | ||
29 | #include <linux/time.h> | 28 | #include <linux/time.h> |
30 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
31 | #include <linux/mm.h> | 30 | #include <linux/mm.h> |
32 | #include <linux/stat.h> | 31 | #include <linux/stat.h> |
33 | #include "ncplib_kernel.h" | 32 | #include "ncp_fs.h" |
34 | |||
35 | 33 | ||
36 | /* these magic numbers must appear in the symlink file -- this makes it a bit | 34 | /* these magic numbers must appear in the symlink file -- this makes it a bit |
37 | more resilient against the magic attributes being set on random files. */ | 35 | more resilient against the magic attributes being set on random files. */ |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index abe4f0c8dc5f..df8c03a02161 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -439,7 +439,6 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry) | |||
439 | if (dentry == NULL) | 439 | if (dentry == NULL) |
440 | return; | 440 | return; |
441 | 441 | ||
442 | d_set_d_op(dentry, NFS_PROTO(dir)->dentry_ops); | ||
443 | inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr); | 442 | inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr); |
444 | if (IS_ERR(inode)) | 443 | if (IS_ERR(inode)) |
445 | goto out; | 444 | goto out; |
@@ -1193,8 +1192,6 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru | |||
1193 | if (dentry->d_name.len > NFS_SERVER(dir)->namelen) | 1192 | if (dentry->d_name.len > NFS_SERVER(dir)->namelen) |
1194 | goto out; | 1193 | goto out; |
1195 | 1194 | ||
1196 | d_set_d_op(dentry, NFS_PROTO(dir)->dentry_ops); | ||
1197 | |||
1198 | /* | 1195 | /* |
1199 | * If we're doing an exclusive create, optimize away the lookup | 1196 | * If we're doing an exclusive create, optimize away the lookup |
1200 | * but don't hash the dentry. | 1197 | * but don't hash the dentry. |
@@ -1338,7 +1335,6 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry | |||
1338 | res = ERR_PTR(-ENAMETOOLONG); | 1335 | res = ERR_PTR(-ENAMETOOLONG); |
1339 | goto out; | 1336 | goto out; |
1340 | } | 1337 | } |
1341 | d_set_d_op(dentry, NFS_PROTO(dir)->dentry_ops); | ||
1342 | 1338 | ||
1343 | /* Let vfs_create() deal with O_EXCL. Instantiate, but don't hash | 1339 | /* Let vfs_create() deal with O_EXCL. Instantiate, but don't hash |
1344 | * the dentry. */ | 1340 | * the dentry. */ |
@@ -1410,11 +1406,15 @@ no_open: | |||
1410 | static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd) | 1406 | static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd) |
1411 | { | 1407 | { |
1412 | struct dentry *parent = NULL; | 1408 | struct dentry *parent = NULL; |
1413 | struct inode *inode = dentry->d_inode; | 1409 | struct inode *inode; |
1414 | struct inode *dir; | 1410 | struct inode *dir; |
1415 | struct nfs_open_context *ctx; | 1411 | struct nfs_open_context *ctx; |
1416 | int openflags, ret = 0; | 1412 | int openflags, ret = 0; |
1417 | 1413 | ||
1414 | if (nd->flags & LOOKUP_RCU) | ||
1415 | return -ECHILD; | ||
1416 | |||
1417 | inode = dentry->d_inode; | ||
1418 | if (!is_atomic_open(nd) || d_mountpoint(dentry)) | 1418 | if (!is_atomic_open(nd) || d_mountpoint(dentry)) |
1419 | goto no_open; | 1419 | goto no_open; |
1420 | 1420 | ||
@@ -1583,6 +1583,7 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
1583 | { | 1583 | { |
1584 | struct iattr attr; | 1584 | struct iattr attr; |
1585 | int error; | 1585 | int error; |
1586 | int open_flags = 0; | ||
1586 | 1587 | ||
1587 | dfprintk(VFS, "NFS: create(%s/%ld), %s\n", | 1588 | dfprintk(VFS, "NFS: create(%s/%ld), %s\n", |
1588 | dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); | 1589 | dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); |
@@ -1590,7 +1591,10 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
1590 | attr.ia_mode = mode; | 1591 | attr.ia_mode = mode; |
1591 | attr.ia_valid = ATTR_MODE; | 1592 | attr.ia_valid = ATTR_MODE; |
1592 | 1593 | ||
1593 | error = NFS_PROTO(dir)->create(dir, dentry, &attr, 0, NULL); | 1594 | if ((nd->flags & LOOKUP_CREATE) != 0) |
1595 | open_flags = nd->intent.open.flags; | ||
1596 | |||
1597 | error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, NULL); | ||
1594 | if (error != 0) | 1598 | if (error != 0) |
1595 | goto out_err; | 1599 | goto out_err; |
1596 | return 0; | 1600 | return 0; |
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c index 5596c6a2881e..b5ffe8fa291f 100644 --- a/fs/nfs/getroot.c +++ b/fs/nfs/getroot.c | |||
@@ -119,9 +119,6 @@ struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh) | |||
119 | } | 119 | } |
120 | 120 | ||
121 | security_d_instantiate(ret, inode); | 121 | security_d_instantiate(ret, inode); |
122 | |||
123 | if (ret->d_op == NULL) | ||
124 | d_set_d_op(ret, server->nfs_client->rpc_ops->dentry_ops); | ||
125 | out: | 122 | out: |
126 | nfs_free_fattr(fsinfo.fattr); | 123 | nfs_free_fattr(fsinfo.fattr); |
127 | return ret; | 124 | return ret; |
@@ -227,9 +224,6 @@ struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh) | |||
227 | 224 | ||
228 | security_d_instantiate(ret, inode); | 225 | security_d_instantiate(ret, inode); |
229 | 226 | ||
230 | if (ret->d_op == NULL) | ||
231 | d_set_d_op(ret, server->nfs_client->rpc_ops->dentry_ops); | ||
232 | |||
233 | out: | 227 | out: |
234 | nfs_free_fattr(fattr); | 228 | nfs_free_fattr(fattr); |
235 | dprintk("<-- nfs4_get_root()\n"); | 229 | dprintk("<-- nfs4_get_root()\n"); |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 0f9ea73e7789..b68c8607770f 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -2202,6 +2202,7 @@ static int nfs_set_super(struct super_block *s, void *data) | |||
2202 | 2202 | ||
2203 | s->s_flags = sb_mntdata->mntflags; | 2203 | s->s_flags = sb_mntdata->mntflags; |
2204 | s->s_fs_info = server; | 2204 | s->s_fs_info = server; |
2205 | s->s_d_op = server->nfs_client->rpc_ops->dentry_ops; | ||
2205 | ret = set_anon_super(s, server); | 2206 | ret = set_anon_super(s, server); |
2206 | if (ret == 0) | 2207 | if (ret == 0) |
2207 | server->s_dev = s->s_dev; | 2208 | server->s_dev = s->s_dev; |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 3a359023c9f7..230b79fbf005 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -845,11 +845,6 @@ nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf, | |||
845 | struct page **pp = rqstp->rq_respages + rqstp->rq_resused; | 845 | struct page **pp = rqstp->rq_respages + rqstp->rq_resused; |
846 | struct page *page = buf->page; | 846 | struct page *page = buf->page; |
847 | size_t size; | 847 | size_t size; |
848 | int ret; | ||
849 | |||
850 | ret = buf->ops->confirm(pipe, buf); | ||
851 | if (unlikely(ret)) | ||
852 | return ret; | ||
853 | 848 | ||
854 | size = sd->len; | 849 | size = sd->len; |
855 | 850 | ||
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 70dfdd532b83..0994f6a76c07 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c | |||
@@ -1163,14 +1163,14 @@ nilfs_mount(struct file_system_type *fs_type, int flags, | |||
1163 | { | 1163 | { |
1164 | struct nilfs_super_data sd; | 1164 | struct nilfs_super_data sd; |
1165 | struct super_block *s; | 1165 | struct super_block *s; |
1166 | fmode_t mode = FMODE_READ; | 1166 | fmode_t mode = FMODE_READ | FMODE_EXCL; |
1167 | struct dentry *root_dentry; | 1167 | struct dentry *root_dentry; |
1168 | int err, s_new = false; | 1168 | int err, s_new = false; |
1169 | 1169 | ||
1170 | if (!(flags & MS_RDONLY)) | 1170 | if (!(flags & MS_RDONLY)) |
1171 | mode |= FMODE_WRITE; | 1171 | mode |= FMODE_WRITE; |
1172 | 1172 | ||
1173 | sd.bdev = open_bdev_exclusive(dev_name, mode, fs_type); | 1173 | sd.bdev = blkdev_get_by_path(dev_name, mode, fs_type); |
1174 | if (IS_ERR(sd.bdev)) | 1174 | if (IS_ERR(sd.bdev)) |
1175 | return ERR_CAST(sd.bdev); | 1175 | return ERR_CAST(sd.bdev); |
1176 | 1176 | ||
@@ -1249,7 +1249,7 @@ nilfs_mount(struct file_system_type *fs_type, int flags, | |||
1249 | } | 1249 | } |
1250 | 1250 | ||
1251 | if (!s_new) | 1251 | if (!s_new) |
1252 | close_bdev_exclusive(sd.bdev, mode); | 1252 | blkdev_put(sd.bdev, mode); |
1253 | 1253 | ||
1254 | return root_dentry; | 1254 | return root_dentry; |
1255 | 1255 | ||
@@ -1258,7 +1258,7 @@ nilfs_mount(struct file_system_type *fs_type, int flags, | |||
1258 | 1258 | ||
1259 | failed: | 1259 | failed: |
1260 | if (!s_new) | 1260 | if (!s_new) |
1261 | close_bdev_exclusive(sd.bdev, mode); | 1261 | blkdev_put(sd.bdev, mode); |
1262 | return ERR_PTR(err); | 1262 | return ERR_PTR(err); |
1263 | } | 1263 | } |
1264 | 1264 | ||
diff --git a/fs/notify/fanotify/Kconfig b/fs/notify/fanotify/Kconfig index 3ac36b7bf6b9..7dceff005a67 100644 --- a/fs/notify/fanotify/Kconfig +++ b/fs/notify/fanotify/Kconfig | |||
@@ -6,7 +6,7 @@ config FANOTIFY | |||
6 | ---help--- | 6 | ---help--- |
7 | Say Y here to enable fanotify suport. fanotify is a file access | 7 | Say Y here to enable fanotify suport. fanotify is a file access |
8 | notification system which differs from inotify in that it sends | 8 | notification system which differs from inotify in that it sends |
9 | and open file descriptor to the userspace listener along with | 9 | an open file descriptor to the userspace listener along with |
10 | the event. | 10 | the event. |
11 | 11 | ||
12 | If unsure, say Y. | 12 | If unsure, say Y. |
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index a6cc05302e9f..b108e863d8f6 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c | |||
@@ -1729,7 +1729,7 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, | |||
1729 | goto out; | 1729 | goto out; |
1730 | 1730 | ||
1731 | reg->hr_bdev = I_BDEV(filp->f_mapping->host); | 1731 | reg->hr_bdev = I_BDEV(filp->f_mapping->host); |
1732 | ret = blkdev_get(reg->hr_bdev, FMODE_WRITE | FMODE_READ); | 1732 | ret = blkdev_get(reg->hr_bdev, FMODE_WRITE | FMODE_READ, NULL); |
1733 | if (ret) { | 1733 | if (ret) { |
1734 | reg->hr_bdev = NULL; | 1734 | reg->hr_bdev = NULL; |
1735 | goto out; | 1735 | goto out; |
diff --git a/fs/ocfs2/export.c b/fs/ocfs2/export.c index 6adafa576065..5dbc3062b4fd 100644 --- a/fs/ocfs2/export.c +++ b/fs/ocfs2/export.c | |||
@@ -137,9 +137,7 @@ check_gen: | |||
137 | } | 137 | } |
138 | 138 | ||
139 | result = d_obtain_alias(inode); | 139 | result = d_obtain_alias(inode); |
140 | if (!IS_ERR(result)) | 140 | if (IS_ERR(result)) |
141 | d_set_d_op(result, &ocfs2_dentry_ops); | ||
142 | else | ||
143 | mlog_errno(PTR_ERR(result)); | 141 | mlog_errno(PTR_ERR(result)); |
144 | 142 | ||
145 | bail: | 143 | bail: |
@@ -175,8 +173,6 @@ static struct dentry *ocfs2_get_parent(struct dentry *child) | |||
175 | } | 173 | } |
176 | 174 | ||
177 | parent = d_obtain_alias(ocfs2_iget(OCFS2_SB(dir->i_sb), blkno, 0, 0)); | 175 | parent = d_obtain_alias(ocfs2_iget(OCFS2_SB(dir->i_sb), blkno, 0, 0)); |
178 | if (!IS_ERR(parent)) | ||
179 | d_set_d_op(parent, &ocfs2_dentry_ops); | ||
180 | 176 | ||
181 | bail_unlock: | 177 | bail_unlock: |
182 | ocfs2_inode_unlock(dir, 0); | 178 | ocfs2_inode_unlock(dir, 0); |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index bdadbae09094..63e3fca266e0 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -1995,6 +1995,7 @@ static long ocfs2_fallocate(struct inode *inode, int mode, loff_t offset, | |||
1995 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 1995 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
1996 | struct ocfs2_space_resv sr; | 1996 | struct ocfs2_space_resv sr; |
1997 | int change_size = 1; | 1997 | int change_size = 1; |
1998 | int cmd = OCFS2_IOC_RESVSP64; | ||
1998 | 1999 | ||
1999 | if (!ocfs2_writes_unwritten_extents(osb)) | 2000 | if (!ocfs2_writes_unwritten_extents(osb)) |
2000 | return -EOPNOTSUPP; | 2001 | return -EOPNOTSUPP; |
@@ -2005,12 +2006,15 @@ static long ocfs2_fallocate(struct inode *inode, int mode, loff_t offset, | |||
2005 | if (mode & FALLOC_FL_KEEP_SIZE) | 2006 | if (mode & FALLOC_FL_KEEP_SIZE) |
2006 | change_size = 0; | 2007 | change_size = 0; |
2007 | 2008 | ||
2009 | if (mode & FALLOC_FL_PUNCH_HOLE) | ||
2010 | cmd = OCFS2_IOC_UNRESVSP64; | ||
2011 | |||
2008 | sr.l_whence = 0; | 2012 | sr.l_whence = 0; |
2009 | sr.l_start = (s64)offset; | 2013 | sr.l_start = (s64)offset; |
2010 | sr.l_len = (s64)len; | 2014 | sr.l_len = (s64)len; |
2011 | 2015 | ||
2012 | return __ocfs2_change_file_space(NULL, inode, offset, | 2016 | return __ocfs2_change_file_space(NULL, inode, offset, cmd, &sr, |
2013 | OCFS2_IOC_RESVSP64, &sr, change_size); | 2017 | change_size); |
2014 | } | 2018 | } |
2015 | 2019 | ||
2016 | int ocfs2_check_range_for_refcount(struct inode *inode, loff_t pos, | 2020 | int ocfs2_check_range_for_refcount(struct inode *inode, loff_t pos, |
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index f935fd6600dd..4068c6c4c6f6 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c | |||
@@ -434,7 +434,7 @@ static int ocfs2_read_locked_inode(struct inode *inode, | |||
434 | * #1 and #2 can be simply solved by never taking the lock | 434 | * #1 and #2 can be simply solved by never taking the lock |
435 | * here for system files (which are the only type we read | 435 | * here for system files (which are the only type we read |
436 | * during mount). It's a heavier approach, but our main | 436 | * during mount). It's a heavier approach, but our main |
437 | * concern is user-accesible files anyway. | 437 | * concern is user-accessible files anyway. |
438 | * | 438 | * |
439 | * #3 works itself out because we'll eventually take the | 439 | * #3 works itself out because we'll eventually take the |
440 | * cluster lock before trusting anything anyway. | 440 | * cluster lock before trusting anything anyway. |
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 30c523144452..849fb4a2e814 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
@@ -147,7 +147,6 @@ static struct dentry *ocfs2_lookup(struct inode *dir, struct dentry *dentry, | |||
147 | spin_unlock(&oi->ip_lock); | 147 | spin_unlock(&oi->ip_lock); |
148 | 148 | ||
149 | bail_add: | 149 | bail_add: |
150 | d_set_d_op(dentry, &ocfs2_dentry_ops); | ||
151 | ret = d_splice_alias(inode, dentry); | 150 | ret = d_splice_alias(inode, dentry); |
152 | 151 | ||
153 | if (inode) { | 152 | if (inode) { |
@@ -415,7 +414,6 @@ static int ocfs2_mknod(struct inode *dir, | |||
415 | mlog_errno(status); | 414 | mlog_errno(status); |
416 | goto leave; | 415 | goto leave; |
417 | } | 416 | } |
418 | d_set_d_op(dentry, &ocfs2_dentry_ops); | ||
419 | 417 | ||
420 | status = ocfs2_add_entry(handle, dentry, inode, | 418 | status = ocfs2_add_entry(handle, dentry, inode, |
421 | OCFS2_I(inode)->ip_blkno, parent_fe_bh, | 419 | OCFS2_I(inode)->ip_blkno, parent_fe_bh, |
@@ -743,7 +741,6 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
743 | } | 741 | } |
744 | 742 | ||
745 | ihold(inode); | 743 | ihold(inode); |
746 | d_set_d_op(dentry, &ocfs2_dentry_ops); | ||
747 | d_instantiate(dentry, inode); | 744 | d_instantiate(dentry, inode); |
748 | 745 | ||
749 | out_commit: | 746 | out_commit: |
@@ -1797,7 +1794,6 @@ static int ocfs2_symlink(struct inode *dir, | |||
1797 | mlog_errno(status); | 1794 | mlog_errno(status); |
1798 | goto bail; | 1795 | goto bail; |
1799 | } | 1796 | } |
1800 | d_set_d_op(dentry, &ocfs2_dentry_ops); | ||
1801 | 1797 | ||
1802 | status = ocfs2_add_entry(handle, dentry, inode, | 1798 | status = ocfs2_add_entry(handle, dentry, inode, |
1803 | le64_to_cpu(fe->i_blkno), parent_fe_bh, | 1799 | le64_to_cpu(fe->i_blkno), parent_fe_bh, |
@@ -2462,7 +2458,6 @@ int ocfs2_mv_orphaned_inode_to_new(struct inode *dir, | |||
2462 | goto out_commit; | 2458 | goto out_commit; |
2463 | } | 2459 | } |
2464 | 2460 | ||
2465 | d_set_d_op(dentry, &ocfs2_dentry_ops); | ||
2466 | d_instantiate(dentry, inode); | 2461 | d_instantiate(dentry, inode); |
2467 | status = 0; | 2462 | status = 0; |
2468 | out_commit: | 2463 | out_commit: |
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index 5fed60de7630..71998d4d61d5 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c | |||
@@ -1916,7 +1916,7 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_alloc_context *ac, | |||
1916 | if (res->sr_bg_blkno) { | 1916 | if (res->sr_bg_blkno) { |
1917 | /* Attempt to short-circuit the usual search mechanism | 1917 | /* Attempt to short-circuit the usual search mechanism |
1918 | * by jumping straight to the most recently used | 1918 | * by jumping straight to the most recently used |
1919 | * allocation group. This helps us mantain some | 1919 | * allocation group. This helps us maintain some |
1920 | * contiguousness across allocations. */ | 1920 | * contiguousness across allocations. */ |
1921 | status = ocfs2_search_one_group(ac, handle, bits_wanted, | 1921 | status = ocfs2_search_one_group(ac, handle, bits_wanted, |
1922 | min_bits, res, &bits_left); | 1922 | min_bits, res, &bits_left); |
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 17ff46fa8a10..06d1f749ca89 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
@@ -2097,6 +2097,7 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
2097 | 2097 | ||
2098 | sb->s_fs_info = osb; | 2098 | sb->s_fs_info = osb; |
2099 | sb->s_op = &ocfs2_sops; | 2099 | sb->s_op = &ocfs2_sops; |
2100 | sb->s_d_op = &ocfs2_dentry_ops; | ||
2100 | sb->s_export_op = &ocfs2_export_ops; | 2101 | sb->s_export_op = &ocfs2_export_ops; |
2101 | sb->s_qcop = &ocfs2_quotactl_ops; | 2102 | sb->s_qcop = &ocfs2_quotactl_ops; |
2102 | sb->dq_op = &ocfs2_quota_operations; | 2103 | sb->dq_op = &ocfs2_quota_operations; |
@@ -223,7 +223,12 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len) | |||
223 | return -EINVAL; | 223 | return -EINVAL; |
224 | 224 | ||
225 | /* Return error if mode is not supported */ | 225 | /* Return error if mode is not supported */ |
226 | if (mode && !(mode & FALLOC_FL_KEEP_SIZE)) | 226 | if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) |
227 | return -EOPNOTSUPP; | ||
228 | |||
229 | /* Punch hole must have keep size set */ | ||
230 | if ((mode & FALLOC_FL_PUNCH_HOLE) && | ||
231 | !(mode & FALLOC_FL_KEEP_SIZE)) | ||
227 | return -EOPNOTSUPP; | 232 | return -EOPNOTSUPP; |
228 | 233 | ||
229 | if (!(file->f_mode & FMODE_WRITE)) | 234 | if (!(file->f_mode & FMODE_WRITE)) |
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 0a8b0ad0c7e2..9c21119512b9 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
@@ -237,6 +237,13 @@ ssize_t part_size_show(struct device *dev, | |||
237 | return sprintf(buf, "%llu\n",(unsigned long long)p->nr_sects); | 237 | return sprintf(buf, "%llu\n",(unsigned long long)p->nr_sects); |
238 | } | 238 | } |
239 | 239 | ||
240 | ssize_t part_ro_show(struct device *dev, | ||
241 | struct device_attribute *attr, char *buf) | ||
242 | { | ||
243 | struct hd_struct *p = dev_to_part(dev); | ||
244 | return sprintf(buf, "%d\n", p->policy ? 1 : 0); | ||
245 | } | ||
246 | |||
240 | ssize_t part_alignment_offset_show(struct device *dev, | 247 | ssize_t part_alignment_offset_show(struct device *dev, |
241 | struct device_attribute *attr, char *buf) | 248 | struct device_attribute *attr, char *buf) |
242 | { | 249 | { |
@@ -312,6 +319,7 @@ ssize_t part_fail_store(struct device *dev, | |||
312 | static DEVICE_ATTR(partition, S_IRUGO, part_partition_show, NULL); | 319 | static DEVICE_ATTR(partition, S_IRUGO, part_partition_show, NULL); |
313 | static DEVICE_ATTR(start, S_IRUGO, part_start_show, NULL); | 320 | static DEVICE_ATTR(start, S_IRUGO, part_start_show, NULL); |
314 | static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL); | 321 | static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL); |
322 | static DEVICE_ATTR(ro, S_IRUGO, part_ro_show, NULL); | ||
315 | static DEVICE_ATTR(alignment_offset, S_IRUGO, part_alignment_offset_show, NULL); | 323 | static DEVICE_ATTR(alignment_offset, S_IRUGO, part_alignment_offset_show, NULL); |
316 | static DEVICE_ATTR(discard_alignment, S_IRUGO, part_discard_alignment_show, | 324 | static DEVICE_ATTR(discard_alignment, S_IRUGO, part_discard_alignment_show, |
317 | NULL); | 325 | NULL); |
@@ -326,6 +334,7 @@ static struct attribute *part_attrs[] = { | |||
326 | &dev_attr_partition.attr, | 334 | &dev_attr_partition.attr, |
327 | &dev_attr_start.attr, | 335 | &dev_attr_start.attr, |
328 | &dev_attr_size.attr, | 336 | &dev_attr_size.attr, |
337 | &dev_attr_ro.attr, | ||
329 | &dev_attr_alignment_offset.attr, | 338 | &dev_attr_alignment_offset.attr, |
330 | &dev_attr_discard_alignment.attr, | 339 | &dev_attr_discard_alignment.attr, |
331 | &dev_attr_stat.attr, | 340 | &dev_attr_stat.attr, |
@@ -372,6 +381,11 @@ static void delete_partition_rcu_cb(struct rcu_head *head) | |||
372 | put_device(part_to_dev(part)); | 381 | put_device(part_to_dev(part)); |
373 | } | 382 | } |
374 | 383 | ||
384 | void __delete_partition(struct hd_struct *part) | ||
385 | { | ||
386 | call_rcu(&part->rcu_head, delete_partition_rcu_cb); | ||
387 | } | ||
388 | |||
375 | void delete_partition(struct gendisk *disk, int partno) | 389 | void delete_partition(struct gendisk *disk, int partno) |
376 | { | 390 | { |
377 | struct disk_part_tbl *ptbl = disk->part_tbl; | 391 | struct disk_part_tbl *ptbl = disk->part_tbl; |
@@ -390,7 +404,7 @@ void delete_partition(struct gendisk *disk, int partno) | |||
390 | kobject_put(part->holder_dir); | 404 | kobject_put(part->holder_dir); |
391 | device_del(part_to_dev(part)); | 405 | device_del(part_to_dev(part)); |
392 | 406 | ||
393 | call_rcu(&part->rcu_head, delete_partition_rcu_cb); | 407 | hd_struct_put(part); |
394 | } | 408 | } |
395 | 409 | ||
396 | static ssize_t whole_disk_show(struct device *dev, | 410 | static ssize_t whole_disk_show(struct device *dev, |
@@ -489,6 +503,7 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno, | |||
489 | if (!dev_get_uevent_suppress(ddev)) | 503 | if (!dev_get_uevent_suppress(ddev)) |
490 | kobject_uevent(&pdev->kobj, KOBJ_ADD); | 504 | kobject_uevent(&pdev->kobj, KOBJ_ADD); |
491 | 505 | ||
506 | hd_ref_init(p); | ||
492 | return p; | 507 | return p; |
493 | 508 | ||
494 | out_free_info: | 509 | out_free_info: |
@@ -507,65 +522,6 @@ out_put: | |||
507 | return ERR_PTR(err); | 522 | return ERR_PTR(err); |
508 | } | 523 | } |
509 | 524 | ||
510 | /* Not exported, helper to add_disk(). */ | ||
511 | void register_disk(struct gendisk *disk) | ||
512 | { | ||
513 | struct device *ddev = disk_to_dev(disk); | ||
514 | struct block_device *bdev; | ||
515 | struct disk_part_iter piter; | ||
516 | struct hd_struct *part; | ||
517 | int err; | ||
518 | |||
519 | ddev->parent = disk->driverfs_dev; | ||
520 | |||
521 | dev_set_name(ddev, disk->disk_name); | ||
522 | |||
523 | /* delay uevents, until we scanned partition table */ | ||
524 | dev_set_uevent_suppress(ddev, 1); | ||
525 | |||
526 | if (device_add(ddev)) | ||
527 | return; | ||
528 | if (!sysfs_deprecated) { | ||
529 | err = sysfs_create_link(block_depr, &ddev->kobj, | ||
530 | kobject_name(&ddev->kobj)); | ||
531 | if (err) { | ||
532 | device_del(ddev); | ||
533 | return; | ||
534 | } | ||
535 | } | ||
536 | disk->part0.holder_dir = kobject_create_and_add("holders", &ddev->kobj); | ||
537 | disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj); | ||
538 | |||
539 | /* No minors to use for partitions */ | ||
540 | if (!disk_partitionable(disk)) | ||
541 | goto exit; | ||
542 | |||
543 | /* No such device (e.g., media were just removed) */ | ||
544 | if (!get_capacity(disk)) | ||
545 | goto exit; | ||
546 | |||
547 | bdev = bdget_disk(disk, 0); | ||
548 | if (!bdev) | ||
549 | goto exit; | ||
550 | |||
551 | bdev->bd_invalidated = 1; | ||
552 | err = blkdev_get(bdev, FMODE_READ); | ||
553 | if (err < 0) | ||
554 | goto exit; | ||
555 | blkdev_put(bdev, FMODE_READ); | ||
556 | |||
557 | exit: | ||
558 | /* announce disk after possible partitions are created */ | ||
559 | dev_set_uevent_suppress(ddev, 0); | ||
560 | kobject_uevent(&ddev->kobj, KOBJ_ADD); | ||
561 | |||
562 | /* announce possible partitions */ | ||
563 | disk_part_iter_init(&piter, disk, 0); | ||
564 | while ((part = disk_part_iter_next(&piter))) | ||
565 | kobject_uevent(&part_to_dev(part)->kobj, KOBJ_ADD); | ||
566 | disk_part_iter_exit(&piter); | ||
567 | } | ||
568 | |||
569 | static bool disk_unlock_native_capacity(struct gendisk *disk) | 525 | static bool disk_unlock_native_capacity(struct gendisk *disk) |
570 | { | 526 | { |
571 | const struct block_device_operations *bdops = disk->fops; | 527 | const struct block_device_operations *bdops = disk->fops; |
@@ -728,33 +684,3 @@ fail: | |||
728 | } | 684 | } |
729 | 685 | ||
730 | EXPORT_SYMBOL(read_dev_sector); | 686 | EXPORT_SYMBOL(read_dev_sector); |
731 | |||
732 | void del_gendisk(struct gendisk *disk) | ||
733 | { | ||
734 | struct disk_part_iter piter; | ||
735 | struct hd_struct *part; | ||
736 | |||
737 | /* invalidate stuff */ | ||
738 | disk_part_iter_init(&piter, disk, | ||
739 | DISK_PITER_INCL_EMPTY | DISK_PITER_REVERSE); | ||
740 | while ((part = disk_part_iter_next(&piter))) { | ||
741 | invalidate_partition(disk, part->partno); | ||
742 | delete_partition(disk, part->partno); | ||
743 | } | ||
744 | disk_part_iter_exit(&piter); | ||
745 | |||
746 | invalidate_partition(disk, 0); | ||
747 | blk_free_devt(disk_to_dev(disk)->devt); | ||
748 | set_capacity(disk, 0); | ||
749 | disk->flags &= ~GENHD_FL_UP; | ||
750 | unlink_gendisk(disk); | ||
751 | part_stat_set_all(&disk->part0, 0); | ||
752 | disk->part0.stamp = 0; | ||
753 | |||
754 | kobject_put(disk->part0.holder_dir); | ||
755 | kobject_put(disk->slave_dir); | ||
756 | disk->driverfs_dev = NULL; | ||
757 | if (!sysfs_deprecated) | ||
758 | sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk))); | ||
759 | device_del(disk_to_dev(disk)); | ||
760 | } | ||
@@ -441,7 +441,7 @@ redo: | |||
441 | break; | 441 | break; |
442 | } | 442 | } |
443 | if (do_wakeup) { | 443 | if (do_wakeup) { |
444 | wake_up_interruptible_sync(&pipe->wait); | 444 | wake_up_interruptible_sync_poll(&pipe->wait, POLLOUT); |
445 | kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); | 445 | kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); |
446 | } | 446 | } |
447 | pipe_wait(pipe); | 447 | pipe_wait(pipe); |
@@ -450,7 +450,7 @@ redo: | |||
450 | 450 | ||
451 | /* Signal writers asynchronously that there is more room. */ | 451 | /* Signal writers asynchronously that there is more room. */ |
452 | if (do_wakeup) { | 452 | if (do_wakeup) { |
453 | wake_up_interruptible_sync(&pipe->wait); | 453 | wake_up_interruptible_sync_poll(&pipe->wait, POLLOUT); |
454 | kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); | 454 | kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); |
455 | } | 455 | } |
456 | if (ret > 0) | 456 | if (ret > 0) |
@@ -612,7 +612,7 @@ redo2: | |||
612 | break; | 612 | break; |
613 | } | 613 | } |
614 | if (do_wakeup) { | 614 | if (do_wakeup) { |
615 | wake_up_interruptible_sync(&pipe->wait); | 615 | wake_up_interruptible_sync_poll(&pipe->wait, POLLIN); |
616 | kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); | 616 | kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); |
617 | do_wakeup = 0; | 617 | do_wakeup = 0; |
618 | } | 618 | } |
@@ -623,7 +623,7 @@ redo2: | |||
623 | out: | 623 | out: |
624 | mutex_unlock(&inode->i_mutex); | 624 | mutex_unlock(&inode->i_mutex); |
625 | if (do_wakeup) { | 625 | if (do_wakeup) { |
626 | wake_up_interruptible_sync(&pipe->wait); | 626 | wake_up_interruptible_sync_poll(&pipe->wait, POLLIN); |
627 | kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); | 627 | kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); |
628 | } | 628 | } |
629 | if (ret > 0) | 629 | if (ret > 0) |
@@ -715,7 +715,7 @@ pipe_release(struct inode *inode, int decr, int decw) | |||
715 | if (!pipe->readers && !pipe->writers) { | 715 | if (!pipe->readers && !pipe->writers) { |
716 | free_pipe_info(inode); | 716 | free_pipe_info(inode); |
717 | } else { | 717 | } else { |
718 | wake_up_interruptible_sync(&pipe->wait); | 718 | wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLOUT); |
719 | kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); | 719 | kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); |
720 | kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); | 720 | kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); |
721 | } | 721 | } |
@@ -1004,7 +1004,6 @@ struct file *create_write_pipe(int flags) | |||
1004 | goto err_inode; | 1004 | goto err_inode; |
1005 | path.mnt = mntget(pipe_mnt); | 1005 | path.mnt = mntget(pipe_mnt); |
1006 | 1006 | ||
1007 | d_set_d_op(path.dentry, &pipefs_dentry_operations); | ||
1008 | d_instantiate(path.dentry, inode); | 1007 | d_instantiate(path.dentry, inode); |
1009 | 1008 | ||
1010 | err = -ENFILE; | 1009 | err = -ENFILE; |
@@ -1266,7 +1265,8 @@ static const struct super_operations pipefs_ops = { | |||
1266 | static struct dentry *pipefs_mount(struct file_system_type *fs_type, | 1265 | static struct dentry *pipefs_mount(struct file_system_type *fs_type, |
1267 | int flags, const char *dev_name, void *data) | 1266 | int flags, const char *dev_name, void *data) |
1268 | { | 1267 | { |
1269 | return mount_pseudo(fs_type, "pipe:", &pipefs_ops, PIPEFS_MAGIC); | 1268 | return mount_pseudo(fs_type, "pipe:", &pipefs_ops, |
1269 | &pipefs_dentry_operations, PIPEFS_MAGIC); | ||
1270 | } | 1270 | } |
1271 | 1271 | ||
1272 | static struct file_system_type pipe_fs_type = { | 1272 | static struct file_system_type pipe_fs_type = { |
diff --git a/fs/proc/Makefile b/fs/proc/Makefile index 288a49e098bf..df434c5f28fb 100644 --- a/fs/proc/Makefile +++ b/fs/proc/Makefile | |||
@@ -10,12 +10,12 @@ proc-$(CONFIG_MMU) := mmu.o task_mmu.o | |||
10 | proc-y += inode.o root.o base.o generic.o array.o \ | 10 | proc-y += inode.o root.o base.o generic.o array.o \ |
11 | proc_tty.o | 11 | proc_tty.o |
12 | proc-y += cmdline.o | 12 | proc-y += cmdline.o |
13 | proc-y += consoles.o | ||
13 | proc-y += cpuinfo.o | 14 | proc-y += cpuinfo.o |
14 | proc-y += devices.o | 15 | proc-y += devices.o |
15 | proc-y += interrupts.o | 16 | proc-y += interrupts.o |
16 | proc-y += loadavg.o | 17 | proc-y += loadavg.o |
17 | proc-y += meminfo.o | 18 | proc-y += meminfo.o |
18 | proc-y += proc_console.o | ||
19 | proc-y += stat.o | 19 | proc-y += stat.o |
20 | proc-y += uptime.o | 20 | proc-y += uptime.o |
21 | proc-y += version.o | 21 | proc-y += version.o |
diff --git a/fs/proc/array.c b/fs/proc/array.c index fff6572676ae..df2b703b9d0f 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c | |||
@@ -95,7 +95,7 @@ static inline void task_name(struct seq_file *m, struct task_struct *p) | |||
95 | 95 | ||
96 | get_task_comm(tcomm, p); | 96 | get_task_comm(tcomm, p); |
97 | 97 | ||
98 | seq_printf(m, "Name:\t"); | 98 | seq_puts(m, "Name:\t"); |
99 | end = m->buf + m->size; | 99 | end = m->buf + m->size; |
100 | buf = m->buf + m->count; | 100 | buf = m->buf + m->count; |
101 | name = tcomm; | 101 | name = tcomm; |
@@ -122,7 +122,7 @@ static inline void task_name(struct seq_file *m, struct task_struct *p) | |||
122 | buf++; | 122 | buf++; |
123 | } | 123 | } |
124 | m->count = buf - m->buf; | 124 | m->count = buf - m->buf; |
125 | seq_printf(m, "\n"); | 125 | seq_putc(m, '\n'); |
126 | } | 126 | } |
127 | 127 | ||
128 | /* | 128 | /* |
@@ -208,7 +208,7 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns, | |||
208 | seq_printf(m, "%d ", GROUP_AT(group_info, g)); | 208 | seq_printf(m, "%d ", GROUP_AT(group_info, g)); |
209 | put_cred(cred); | 209 | put_cred(cred); |
210 | 210 | ||
211 | seq_printf(m, "\n"); | 211 | seq_putc(m, '\n'); |
212 | } | 212 | } |
213 | 213 | ||
214 | static void render_sigset_t(struct seq_file *m, const char *header, | 214 | static void render_sigset_t(struct seq_file *m, const char *header, |
@@ -216,7 +216,7 @@ static void render_sigset_t(struct seq_file *m, const char *header, | |||
216 | { | 216 | { |
217 | int i; | 217 | int i; |
218 | 218 | ||
219 | seq_printf(m, "%s", header); | 219 | seq_puts(m, header); |
220 | 220 | ||
221 | i = _NSIG; | 221 | i = _NSIG; |
222 | do { | 222 | do { |
@@ -230,7 +230,7 @@ static void render_sigset_t(struct seq_file *m, const char *header, | |||
230 | seq_printf(m, "%x", x); | 230 | seq_printf(m, "%x", x); |
231 | } while (i >= 4); | 231 | } while (i >= 4); |
232 | 232 | ||
233 | seq_printf(m, "\n"); | 233 | seq_putc(m, '\n'); |
234 | } | 234 | } |
235 | 235 | ||
236 | static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign, | 236 | static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign, |
@@ -291,12 +291,12 @@ static void render_cap_t(struct seq_file *m, const char *header, | |||
291 | { | 291 | { |
292 | unsigned __capi; | 292 | unsigned __capi; |
293 | 293 | ||
294 | seq_printf(m, "%s", header); | 294 | seq_puts(m, header); |
295 | CAP_FOR_EACH_U32(__capi) { | 295 | CAP_FOR_EACH_U32(__capi) { |
296 | seq_printf(m, "%08x", | 296 | seq_printf(m, "%08x", |
297 | a->cap[(_KERNEL_CAPABILITY_U32S-1) - __capi]); | 297 | a->cap[(_KERNEL_CAPABILITY_U32S-1) - __capi]); |
298 | } | 298 | } |
299 | seq_printf(m, "\n"); | 299 | seq_putc(m, '\n'); |
300 | } | 300 | } |
301 | 301 | ||
302 | static inline void task_cap(struct seq_file *m, struct task_struct *p) | 302 | static inline void task_cap(struct seq_file *m, struct task_struct *p) |
@@ -329,12 +329,12 @@ static inline void task_context_switch_counts(struct seq_file *m, | |||
329 | 329 | ||
330 | static void task_cpus_allowed(struct seq_file *m, struct task_struct *task) | 330 | static void task_cpus_allowed(struct seq_file *m, struct task_struct *task) |
331 | { | 331 | { |
332 | seq_printf(m, "Cpus_allowed:\t"); | 332 | seq_puts(m, "Cpus_allowed:\t"); |
333 | seq_cpumask(m, &task->cpus_allowed); | 333 | seq_cpumask(m, &task->cpus_allowed); |
334 | seq_printf(m, "\n"); | 334 | seq_putc(m, '\n'); |
335 | seq_printf(m, "Cpus_allowed_list:\t"); | 335 | seq_puts(m, "Cpus_allowed_list:\t"); |
336 | seq_cpumask_list(m, &task->cpus_allowed); | 336 | seq_cpumask_list(m, &task->cpus_allowed); |
337 | seq_printf(m, "\n"); | 337 | seq_putc(m, '\n'); |
338 | } | 338 | } |
339 | 339 | ||
340 | int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, | 340 | int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, |
@@ -535,15 +535,15 @@ int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns, | |||
535 | int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns, | 535 | int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns, |
536 | struct pid *pid, struct task_struct *task) | 536 | struct pid *pid, struct task_struct *task) |
537 | { | 537 | { |
538 | int size = 0, resident = 0, shared = 0, text = 0, lib = 0, data = 0; | 538 | unsigned long size = 0, resident = 0, shared = 0, text = 0, data = 0; |
539 | struct mm_struct *mm = get_task_mm(task); | 539 | struct mm_struct *mm = get_task_mm(task); |
540 | 540 | ||
541 | if (mm) { | 541 | if (mm) { |
542 | size = task_statm(mm, &shared, &text, &data, &resident); | 542 | size = task_statm(mm, &shared, &text, &data, &resident); |
543 | mmput(mm); | 543 | mmput(mm); |
544 | } | 544 | } |
545 | seq_printf(m, "%d %d %d %d %d %d %d\n", | 545 | seq_printf(m, "%lu %lu %lu %lu 0 %lu 0\n", |
546 | size, resident, shared, text, lib, data, 0); | 546 | size, resident, shared, text, data); |
547 | 547 | ||
548 | return 0; | 548 | return 0; |
549 | } | 549 | } |
diff --git a/fs/proc/base.c b/fs/proc/base.c index b20962c71a52..9d096e82b201 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -373,26 +373,20 @@ static int lstats_show_proc(struct seq_file *m, void *v) | |||
373 | return -ESRCH; | 373 | return -ESRCH; |
374 | seq_puts(m, "Latency Top version : v0.1\n"); | 374 | seq_puts(m, "Latency Top version : v0.1\n"); |
375 | for (i = 0; i < 32; i++) { | 375 | for (i = 0; i < 32; i++) { |
376 | if (task->latency_record[i].backtrace[0]) { | 376 | struct latency_record *lr = &task->latency_record[i]; |
377 | if (lr->backtrace[0]) { | ||
377 | int q; | 378 | int q; |
378 | seq_printf(m, "%i %li %li ", | 379 | seq_printf(m, "%i %li %li", |
379 | task->latency_record[i].count, | 380 | lr->count, lr->time, lr->max); |
380 | task->latency_record[i].time, | ||
381 | task->latency_record[i].max); | ||
382 | for (q = 0; q < LT_BACKTRACEDEPTH; q++) { | 381 | for (q = 0; q < LT_BACKTRACEDEPTH; q++) { |
383 | char sym[KSYM_SYMBOL_LEN]; | 382 | unsigned long bt = lr->backtrace[q]; |
384 | char *c; | 383 | if (!bt) |
385 | if (!task->latency_record[i].backtrace[q]) | ||
386 | break; | 384 | break; |
387 | if (task->latency_record[i].backtrace[q] == ULONG_MAX) | 385 | if (bt == ULONG_MAX) |
388 | break; | 386 | break; |
389 | sprint_symbol(sym, task->latency_record[i].backtrace[q]); | 387 | seq_printf(m, " %ps", (void *)bt); |
390 | c = strchr(sym, '+'); | ||
391 | if (c) | ||
392 | *c = 0; | ||
393 | seq_printf(m, "%s ", sym); | ||
394 | } | 388 | } |
395 | seq_printf(m, "\n"); | 389 | seq_putc(m, '\n'); |
396 | } | 390 | } |
397 | 391 | ||
398 | } | 392 | } |
@@ -751,14 +745,7 @@ static int proc_single_show(struct seq_file *m, void *v) | |||
751 | 745 | ||
752 | static int proc_single_open(struct inode *inode, struct file *filp) | 746 | static int proc_single_open(struct inode *inode, struct file *filp) |
753 | { | 747 | { |
754 | int ret; | 748 | return single_open(filp, proc_single_show, inode); |
755 | ret = single_open(filp, proc_single_show, NULL); | ||
756 | if (!ret) { | ||
757 | struct seq_file *m = filp->private_data; | ||
758 | |||
759 | m->private = inode; | ||
760 | } | ||
761 | return ret; | ||
762 | } | 749 | } |
763 | 750 | ||
764 | static const struct file_operations proc_single_file_operations = { | 751 | static const struct file_operations proc_single_file_operations = { |
@@ -1164,7 +1151,7 @@ static ssize_t oom_score_adj_write(struct file *file, const char __user *buf, | |||
1164 | goto err_task_lock; | 1151 | goto err_task_lock; |
1165 | } | 1152 | } |
1166 | 1153 | ||
1167 | if (oom_score_adj < task->signal->oom_score_adj && | 1154 | if (oom_score_adj < task->signal->oom_score_adj_min && |
1168 | !capable(CAP_SYS_RESOURCE)) { | 1155 | !capable(CAP_SYS_RESOURCE)) { |
1169 | err = -EACCES; | 1156 | err = -EACCES; |
1170 | goto err_sighand; | 1157 | goto err_sighand; |
@@ -1177,6 +1164,8 @@ static ssize_t oom_score_adj_write(struct file *file, const char __user *buf, | |||
1177 | atomic_dec(&task->mm->oom_disable_count); | 1164 | atomic_dec(&task->mm->oom_disable_count); |
1178 | } | 1165 | } |
1179 | task->signal->oom_score_adj = oom_score_adj; | 1166 | task->signal->oom_score_adj = oom_score_adj; |
1167 | if (has_capability_noaudit(current, CAP_SYS_RESOURCE)) | ||
1168 | task->signal->oom_score_adj_min = oom_score_adj; | ||
1180 | /* | 1169 | /* |
1181 | * Scale /proc/pid/oom_adj appropriately ensuring that OOM_DISABLE is | 1170 | * Scale /proc/pid/oom_adj appropriately ensuring that OOM_DISABLE is |
1182 | * always attainable. | 1171 | * always attainable. |
@@ -1386,15 +1375,7 @@ sched_write(struct file *file, const char __user *buf, | |||
1386 | 1375 | ||
1387 | static int sched_open(struct inode *inode, struct file *filp) | 1376 | static int sched_open(struct inode *inode, struct file *filp) |
1388 | { | 1377 | { |
1389 | int ret; | 1378 | return single_open(filp, sched_show, inode); |
1390 | |||
1391 | ret = single_open(filp, sched_show, NULL); | ||
1392 | if (!ret) { | ||
1393 | struct seq_file *m = filp->private_data; | ||
1394 | |||
1395 | m->private = inode; | ||
1396 | } | ||
1397 | return ret; | ||
1398 | } | 1379 | } |
1399 | 1380 | ||
1400 | static const struct file_operations proc_pid_sched_operations = { | 1381 | static const struct file_operations proc_pid_sched_operations = { |
@@ -1530,15 +1511,7 @@ static int comm_show(struct seq_file *m, void *v) | |||
1530 | 1511 | ||
1531 | static int comm_open(struct inode *inode, struct file *filp) | 1512 | static int comm_open(struct inode *inode, struct file *filp) |
1532 | { | 1513 | { |
1533 | int ret; | 1514 | return single_open(filp, comm_show, inode); |
1534 | |||
1535 | ret = single_open(filp, comm_show, NULL); | ||
1536 | if (!ret) { | ||
1537 | struct seq_file *m = filp->private_data; | ||
1538 | |||
1539 | m->private = inode; | ||
1540 | } | ||
1541 | return ret; | ||
1542 | } | 1515 | } |
1543 | 1516 | ||
1544 | static const struct file_operations proc_pid_set_comm_operations = { | 1517 | static const struct file_operations proc_pid_set_comm_operations = { |
diff --git a/fs/proc/proc_console.c b/fs/proc/consoles.c index 8a707609f528..eafc22ab1fdd 100644 --- a/fs/proc/proc_console.c +++ b/fs/proc/consoles.c | |||
@@ -106,9 +106,9 @@ static const struct file_operations proc_consoles_operations = { | |||
106 | .release = seq_release, | 106 | .release = seq_release, |
107 | }; | 107 | }; |
108 | 108 | ||
109 | static int register_proc_consoles(void) | 109 | static int __init proc_consoles_init(void) |
110 | { | 110 | { |
111 | proc_create("consoles", 0, NULL, &proc_consoles_operations); | 111 | proc_create("consoles", 0, NULL, &proc_consoles_operations); |
112 | return 0; | 112 | return 0; |
113 | } | 113 | } |
114 | module_init(register_proc_consoles); | 114 | module_init(proc_consoles_init); |
diff --git a/fs/proc/devices.c b/fs/proc/devices.c index 59ee7da959c9..b14347167c35 100644 --- a/fs/proc/devices.c +++ b/fs/proc/devices.c | |||
@@ -9,14 +9,14 @@ static int devinfo_show(struct seq_file *f, void *v) | |||
9 | 9 | ||
10 | if (i < CHRDEV_MAJOR_HASH_SIZE) { | 10 | if (i < CHRDEV_MAJOR_HASH_SIZE) { |
11 | if (i == 0) | 11 | if (i == 0) |
12 | seq_printf(f, "Character devices:\n"); | 12 | seq_puts(f, "Character devices:\n"); |
13 | chrdev_show(f, i); | 13 | chrdev_show(f, i); |
14 | } | 14 | } |
15 | #ifdef CONFIG_BLOCK | 15 | #ifdef CONFIG_BLOCK |
16 | else { | 16 | else { |
17 | i -= CHRDEV_MAJOR_HASH_SIZE; | 17 | i -= CHRDEV_MAJOR_HASH_SIZE; |
18 | if (i == 0) | 18 | if (i == 0) |
19 | seq_printf(f, "\nBlock devices:\n"); | 19 | seq_puts(f, "\nBlock devices:\n"); |
20 | blkdev_show(f, i); | 20 | blkdev_show(f, i); |
21 | } | 21 | } |
22 | #endif | 22 | #endif |
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index f766be29d2c7..01e07f2a188f 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c | |||
@@ -425,13 +425,10 @@ struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir, | |||
425 | if (de->namelen != dentry->d_name.len) | 425 | if (de->namelen != dentry->d_name.len) |
426 | continue; | 426 | continue; |
427 | if (!memcmp(dentry->d_name.name, de->name, de->namelen)) { | 427 | if (!memcmp(dentry->d_name.name, de->name, de->namelen)) { |
428 | unsigned int ino; | ||
429 | |||
430 | ino = de->low_ino; | ||
431 | pde_get(de); | 428 | pde_get(de); |
432 | spin_unlock(&proc_subdir_lock); | 429 | spin_unlock(&proc_subdir_lock); |
433 | error = -EINVAL; | 430 | error = -EINVAL; |
434 | inode = proc_get_inode(dir->i_sb, ino, de); | 431 | inode = proc_get_inode(dir->i_sb, de); |
435 | goto out_unlock; | 432 | goto out_unlock; |
436 | } | 433 | } |
437 | } | 434 | } |
@@ -768,12 +765,7 @@ EXPORT_SYMBOL(proc_create_data); | |||
768 | 765 | ||
769 | static void free_proc_entry(struct proc_dir_entry *de) | 766 | static void free_proc_entry(struct proc_dir_entry *de) |
770 | { | 767 | { |
771 | unsigned int ino = de->low_ino; | 768 | release_inode_number(de->low_ino); |
772 | |||
773 | if (ino < PROC_DYNAMIC_FIRST) | ||
774 | return; | ||
775 | |||
776 | release_inode_number(ino); | ||
777 | 769 | ||
778 | if (S_ISLNK(de->mode)) | 770 | if (S_ISLNK(de->mode)) |
779 | kfree(de->data); | 771 | kfree(de->data); |
@@ -834,12 +826,9 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent) | |||
834 | 826 | ||
835 | wait_for_completion(de->pde_unload_completion); | 827 | wait_for_completion(de->pde_unload_completion); |
836 | 828 | ||
837 | goto continue_removing; | 829 | spin_lock(&de->pde_unload_lock); |
838 | } | 830 | } |
839 | spin_unlock(&de->pde_unload_lock); | ||
840 | 831 | ||
841 | continue_removing: | ||
842 | spin_lock(&de->pde_unload_lock); | ||
843 | while (!list_empty(&de->pde_openers)) { | 832 | while (!list_empty(&de->pde_openers)) { |
844 | struct pde_opener *pdeo; | 833 | struct pde_opener *pdeo; |
845 | 834 | ||
diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 6bcb926b101b..176ce4cda68a 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c | |||
@@ -416,12 +416,11 @@ static const struct file_operations proc_reg_file_ops_no_compat = { | |||
416 | }; | 416 | }; |
417 | #endif | 417 | #endif |
418 | 418 | ||
419 | struct inode *proc_get_inode(struct super_block *sb, unsigned int ino, | 419 | struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de) |
420 | struct proc_dir_entry *de) | ||
421 | { | 420 | { |
422 | struct inode * inode; | 421 | struct inode * inode; |
423 | 422 | ||
424 | inode = iget_locked(sb, ino); | 423 | inode = iget_locked(sb, de->low_ino); |
425 | if (!inode) | 424 | if (!inode) |
426 | return NULL; | 425 | return NULL; |
427 | if (inode->i_state & I_NEW) { | 426 | if (inode->i_state & I_NEW) { |
@@ -471,7 +470,7 @@ int proc_fill_super(struct super_block *s) | |||
471 | s->s_time_gran = 1; | 470 | s->s_time_gran = 1; |
472 | 471 | ||
473 | pde_get(&proc_root); | 472 | pde_get(&proc_root); |
474 | root_inode = proc_get_inode(s, PROC_ROOT_INO, &proc_root); | 473 | root_inode = proc_get_inode(s, &proc_root); |
475 | if (!root_inode) | 474 | if (!root_inode) |
476 | goto out_no_root; | 475 | goto out_no_root; |
477 | root_inode->i_uid = 0; | 476 | root_inode->i_uid = 0; |
diff --git a/fs/proc/internal.h b/fs/proc/internal.h index 1f24a3eddd12..9ad561ded409 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h | |||
@@ -96,7 +96,8 @@ extern spinlock_t proc_subdir_lock; | |||
96 | struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *); | 96 | struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *); |
97 | int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir); | 97 | int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir); |
98 | unsigned long task_vsize(struct mm_struct *); | 98 | unsigned long task_vsize(struct mm_struct *); |
99 | int task_statm(struct mm_struct *, int *, int *, int *, int *); | 99 | unsigned long task_statm(struct mm_struct *, |
100 | unsigned long *, unsigned long *, unsigned long *, unsigned long *); | ||
100 | void task_mem(struct seq_file *, struct mm_struct *); | 101 | void task_mem(struct seq_file *, struct mm_struct *); |
101 | 102 | ||
102 | static inline struct proc_dir_entry *pde_get(struct proc_dir_entry *pde) | 103 | static inline struct proc_dir_entry *pde_get(struct proc_dir_entry *pde) |
@@ -108,7 +109,7 @@ void pde_put(struct proc_dir_entry *pde); | |||
108 | 109 | ||
109 | extern struct vfsmount *proc_mnt; | 110 | extern struct vfsmount *proc_mnt; |
110 | int proc_fill_super(struct super_block *); | 111 | int proc_fill_super(struct super_block *); |
111 | struct inode *proc_get_inode(struct super_block *, unsigned int, struct proc_dir_entry *); | 112 | struct inode *proc_get_inode(struct super_block *, struct proc_dir_entry *); |
112 | 113 | ||
113 | /* | 114 | /* |
114 | * These are generic /proc routines that use the internal | 115 | * These are generic /proc routines that use the internal |
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index 6f37c391468d..d245cb23dd72 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c | |||
@@ -558,7 +558,7 @@ static int open_kcore(struct inode *inode, struct file *filp) | |||
558 | static const struct file_operations proc_kcore_operations = { | 558 | static const struct file_operations proc_kcore_operations = { |
559 | .read = read_kcore, | 559 | .read = read_kcore, |
560 | .open = open_kcore, | 560 | .open = open_kcore, |
561 | .llseek = generic_file_llseek, | 561 | .llseek = default_llseek, |
562 | }; | 562 | }; |
563 | 563 | ||
564 | #ifdef CONFIG_MEMORY_HOTPLUG | 564 | #ifdef CONFIG_MEMORY_HOTPLUG |
diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c index a65239cfd97e..ed257d141568 100644 --- a/fs/proc/meminfo.c +++ b/fs/proc/meminfo.c | |||
@@ -101,6 +101,9 @@ static int meminfo_proc_show(struct seq_file *m, void *v) | |||
101 | #ifdef CONFIG_MEMORY_FAILURE | 101 | #ifdef CONFIG_MEMORY_FAILURE |
102 | "HardwareCorrupted: %5lu kB\n" | 102 | "HardwareCorrupted: %5lu kB\n" |
103 | #endif | 103 | #endif |
104 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
105 | "AnonHugePages: %8lu kB\n" | ||
106 | #endif | ||
104 | , | 107 | , |
105 | K(i.totalram), | 108 | K(i.totalram), |
106 | K(i.freeram), | 109 | K(i.freeram), |
@@ -128,7 +131,12 @@ static int meminfo_proc_show(struct seq_file *m, void *v) | |||
128 | K(i.freeswap), | 131 | K(i.freeswap), |
129 | K(global_page_state(NR_FILE_DIRTY)), | 132 | K(global_page_state(NR_FILE_DIRTY)), |
130 | K(global_page_state(NR_WRITEBACK)), | 133 | K(global_page_state(NR_WRITEBACK)), |
131 | K(global_page_state(NR_ANON_PAGES)), | 134 | K(global_page_state(NR_ANON_PAGES) |
135 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
136 | + global_page_state(NR_ANON_TRANSPARENT_HUGEPAGES) * | ||
137 | HPAGE_PMD_NR | ||
138 | #endif | ||
139 | ), | ||
132 | K(global_page_state(NR_FILE_MAPPED)), | 140 | K(global_page_state(NR_FILE_MAPPED)), |
133 | K(global_page_state(NR_SHMEM)), | 141 | K(global_page_state(NR_SHMEM)), |
134 | K(global_page_state(NR_SLAB_RECLAIMABLE) + | 142 | K(global_page_state(NR_SLAB_RECLAIMABLE) + |
@@ -151,6 +159,10 @@ static int meminfo_proc_show(struct seq_file *m, void *v) | |||
151 | #ifdef CONFIG_MEMORY_FAILURE | 159 | #ifdef CONFIG_MEMORY_FAILURE |
152 | ,atomic_long_read(&mce_bad_pages) << (PAGE_SHIFT - 10) | 160 | ,atomic_long_read(&mce_bad_pages) << (PAGE_SHIFT - 10) |
153 | #endif | 161 | #endif |
162 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
163 | ,K(global_page_state(NR_ANON_TRANSPARENT_HUGEPAGES) * | ||
164 | HPAGE_PMD_NR) | ||
165 | #endif | ||
154 | ); | 166 | ); |
155 | 167 | ||
156 | hugetlb_report_meminfo(m); | 168 | hugetlb_report_meminfo(m); |
diff --git a/fs/proc/page.c b/fs/proc/page.c index 3b8b45660331..6d8e6a9e93ab 100644 --- a/fs/proc/page.c +++ b/fs/proc/page.c | |||
@@ -40,7 +40,7 @@ static ssize_t kpagecount_read(struct file *file, char __user *buf, | |||
40 | ppage = pfn_to_page(pfn); | 40 | ppage = pfn_to_page(pfn); |
41 | else | 41 | else |
42 | ppage = NULL; | 42 | ppage = NULL; |
43 | if (!ppage) | 43 | if (!ppage || PageSlab(ppage)) |
44 | pcount = 0; | 44 | pcount = 0; |
45 | else | 45 | else |
46 | pcount = page_mapcount(ppage); | 46 | pcount = page_mapcount(ppage); |
@@ -116,15 +116,17 @@ u64 stable_page_flags(struct page *page) | |||
116 | if (PageHuge(page)) | 116 | if (PageHuge(page)) |
117 | u |= 1 << KPF_HUGE; | 117 | u |= 1 << KPF_HUGE; |
118 | 118 | ||
119 | u |= kpf_copy_bit(k, KPF_LOCKED, PG_locked); | ||
120 | |||
121 | /* | 119 | /* |
122 | * Caveats on high order pages: | 120 | * Caveats on high order pages: page->_count will only be set |
123 | * PG_buddy will only be set on the head page; SLUB/SLQB do the same | 121 | * -1 on the head page; SLUB/SLQB do the same for PG_slab; |
124 | * for PG_slab; SLOB won't set PG_slab at all on compound pages. | 122 | * SLOB won't set PG_slab at all on compound pages. |
125 | */ | 123 | */ |
124 | if (PageBuddy(page)) | ||
125 | u |= 1 << KPF_BUDDY; | ||
126 | |||
127 | u |= kpf_copy_bit(k, KPF_LOCKED, PG_locked); | ||
128 | |||
126 | u |= kpf_copy_bit(k, KPF_SLAB, PG_slab); | 129 | u |= kpf_copy_bit(k, KPF_SLAB, PG_slab); |
127 | u |= kpf_copy_bit(k, KPF_BUDDY, PG_buddy); | ||
128 | 130 | ||
129 | u |= kpf_copy_bit(k, KPF_ERROR, PG_error); | 131 | u |= kpf_copy_bit(k, KPF_ERROR, PG_error); |
130 | u |= kpf_copy_bit(k, KPF_DIRTY, PG_dirty); | 132 | u |= kpf_copy_bit(k, KPF_DIRTY, PG_dirty); |
diff --git a/fs/proc/proc_tty.c b/fs/proc/proc_tty.c index 83adcc869437..cb761f010300 100644 --- a/fs/proc/proc_tty.c +++ b/fs/proc/proc_tty.c | |||
@@ -36,27 +36,27 @@ static void show_tty_range(struct seq_file *m, struct tty_driver *p, | |||
36 | } | 36 | } |
37 | switch (p->type) { | 37 | switch (p->type) { |
38 | case TTY_DRIVER_TYPE_SYSTEM: | 38 | case TTY_DRIVER_TYPE_SYSTEM: |
39 | seq_printf(m, "system"); | 39 | seq_puts(m, "system"); |
40 | if (p->subtype == SYSTEM_TYPE_TTY) | 40 | if (p->subtype == SYSTEM_TYPE_TTY) |
41 | seq_printf(m, ":/dev/tty"); | 41 | seq_puts(m, ":/dev/tty"); |
42 | else if (p->subtype == SYSTEM_TYPE_SYSCONS) | 42 | else if (p->subtype == SYSTEM_TYPE_SYSCONS) |
43 | seq_printf(m, ":console"); | 43 | seq_puts(m, ":console"); |
44 | else if (p->subtype == SYSTEM_TYPE_CONSOLE) | 44 | else if (p->subtype == SYSTEM_TYPE_CONSOLE) |
45 | seq_printf(m, ":vtmaster"); | 45 | seq_puts(m, ":vtmaster"); |
46 | break; | 46 | break; |
47 | case TTY_DRIVER_TYPE_CONSOLE: | 47 | case TTY_DRIVER_TYPE_CONSOLE: |
48 | seq_printf(m, "console"); | 48 | seq_puts(m, "console"); |
49 | break; | 49 | break; |
50 | case TTY_DRIVER_TYPE_SERIAL: | 50 | case TTY_DRIVER_TYPE_SERIAL: |
51 | seq_printf(m, "serial"); | 51 | seq_puts(m, "serial"); |
52 | break; | 52 | break; |
53 | case TTY_DRIVER_TYPE_PTY: | 53 | case TTY_DRIVER_TYPE_PTY: |
54 | if (p->subtype == PTY_TYPE_MASTER) | 54 | if (p->subtype == PTY_TYPE_MASTER) |
55 | seq_printf(m, "pty:master"); | 55 | seq_puts(m, "pty:master"); |
56 | else if (p->subtype == PTY_TYPE_SLAVE) | 56 | else if (p->subtype == PTY_TYPE_SLAVE) |
57 | seq_printf(m, "pty:slave"); | 57 | seq_puts(m, "pty:slave"); |
58 | else | 58 | else |
59 | seq_printf(m, "pty"); | 59 | seq_puts(m, "pty"); |
60 | break; | 60 | break; |
61 | default: | 61 | default: |
62 | seq_printf(m, "type:%d.%d", p->type, p->subtype); | 62 | seq_printf(m, "type:%d.%d", p->type, p->subtype); |
@@ -74,19 +74,19 @@ static int show_tty_driver(struct seq_file *m, void *v) | |||
74 | /* pseudo-drivers first */ | 74 | /* pseudo-drivers first */ |
75 | seq_printf(m, "%-20s /dev/%-8s ", "/dev/tty", "tty"); | 75 | seq_printf(m, "%-20s /dev/%-8s ", "/dev/tty", "tty"); |
76 | seq_printf(m, "%3d %7d ", TTYAUX_MAJOR, 0); | 76 | seq_printf(m, "%3d %7d ", TTYAUX_MAJOR, 0); |
77 | seq_printf(m, "system:/dev/tty\n"); | 77 | seq_puts(m, "system:/dev/tty\n"); |
78 | seq_printf(m, "%-20s /dev/%-8s ", "/dev/console", "console"); | 78 | seq_printf(m, "%-20s /dev/%-8s ", "/dev/console", "console"); |
79 | seq_printf(m, "%3d %7d ", TTYAUX_MAJOR, 1); | 79 | seq_printf(m, "%3d %7d ", TTYAUX_MAJOR, 1); |
80 | seq_printf(m, "system:console\n"); | 80 | seq_puts(m, "system:console\n"); |
81 | #ifdef CONFIG_UNIX98_PTYS | 81 | #ifdef CONFIG_UNIX98_PTYS |
82 | seq_printf(m, "%-20s /dev/%-8s ", "/dev/ptmx", "ptmx"); | 82 | seq_printf(m, "%-20s /dev/%-8s ", "/dev/ptmx", "ptmx"); |
83 | seq_printf(m, "%3d %7d ", TTYAUX_MAJOR, 2); | 83 | seq_printf(m, "%3d %7d ", TTYAUX_MAJOR, 2); |
84 | seq_printf(m, "system\n"); | 84 | seq_puts(m, "system\n"); |
85 | #endif | 85 | #endif |
86 | #ifdef CONFIG_VT | 86 | #ifdef CONFIG_VT |
87 | seq_printf(m, "%-20s /dev/%-8s ", "/dev/vc/0", "vc/0"); | 87 | seq_printf(m, "%-20s /dev/%-8s ", "/dev/vc/0", "vc/0"); |
88 | seq_printf(m, "%3d %7d ", TTY_MAJOR, 0); | 88 | seq_printf(m, "%3d %7d ", TTY_MAJOR, 0); |
89 | seq_printf(m, "system:vtmaster\n"); | 89 | seq_puts(m, "system:vtmaster\n"); |
90 | #endif | 90 | #endif |
91 | } | 91 | } |
92 | 92 | ||
diff --git a/fs/proc/softirqs.c b/fs/proc/softirqs.c index 37994737c983..62604be9f58d 100644 --- a/fs/proc/softirqs.c +++ b/fs/proc/softirqs.c | |||
@@ -10,16 +10,16 @@ static int show_softirqs(struct seq_file *p, void *v) | |||
10 | { | 10 | { |
11 | int i, j; | 11 | int i, j; |
12 | 12 | ||
13 | seq_printf(p, " "); | 13 | seq_puts(p, " "); |
14 | for_each_possible_cpu(i) | 14 | for_each_possible_cpu(i) |
15 | seq_printf(p, "CPU%-8d", i); | 15 | seq_printf(p, "CPU%-8d", i); |
16 | seq_printf(p, "\n"); | 16 | seq_putc(p, '\n'); |
17 | 17 | ||
18 | for (i = 0; i < NR_SOFTIRQS; i++) { | 18 | for (i = 0; i < NR_SOFTIRQS; i++) { |
19 | seq_printf(p, "%12s:", softirq_to_name[i]); | 19 | seq_printf(p, "%12s:", softirq_to_name[i]); |
20 | for_each_possible_cpu(j) | 20 | for_each_possible_cpu(j) |
21 | seq_printf(p, " %10u", kstat_softirqs_cpu(i, j)); | 21 | seq_printf(p, " %10u", kstat_softirqs_cpu(i, j)); |
22 | seq_printf(p, "\n"); | 22 | seq_putc(p, '\n'); |
23 | } | 23 | } |
24 | return 0; | 24 | return 0; |
25 | } | 25 | } |
diff --git a/fs/proc/stat.c b/fs/proc/stat.c index e15a19c93bae..1cffa2b8a2fc 100644 --- a/fs/proc/stat.c +++ b/fs/proc/stat.c | |||
@@ -126,7 +126,7 @@ static int show_stat(struct seq_file *p, void *v) | |||
126 | 126 | ||
127 | for (i = 0; i < NR_SOFTIRQS; i++) | 127 | for (i = 0; i < NR_SOFTIRQS; i++) |
128 | seq_printf(p, " %u", per_softirq_sums[i]); | 128 | seq_printf(p, " %u", per_softirq_sums[i]); |
129 | seq_printf(p, "\n"); | 129 | seq_putc(p, '\n'); |
130 | 130 | ||
131 | return 0; | 131 | return 0; |
132 | } | 132 | } |
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index c126c83b9a45..60b914860f81 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -66,8 +66,9 @@ unsigned long task_vsize(struct mm_struct *mm) | |||
66 | return PAGE_SIZE * mm->total_vm; | 66 | return PAGE_SIZE * mm->total_vm; |
67 | } | 67 | } |
68 | 68 | ||
69 | int task_statm(struct mm_struct *mm, int *shared, int *text, | 69 | unsigned long task_statm(struct mm_struct *mm, |
70 | int *data, int *resident) | 70 | unsigned long *shared, unsigned long *text, |
71 | unsigned long *data, unsigned long *resident) | ||
71 | { | 72 | { |
72 | *shared = get_mm_counter(mm, MM_FILEPAGES); | 73 | *shared = get_mm_counter(mm, MM_FILEPAGES); |
73 | *text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) | 74 | *text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) |
@@ -417,7 +418,8 @@ static int show_smap(struct seq_file *m, void *v) | |||
417 | "Anonymous: %8lu kB\n" | 418 | "Anonymous: %8lu kB\n" |
418 | "Swap: %8lu kB\n" | 419 | "Swap: %8lu kB\n" |
419 | "KernelPageSize: %8lu kB\n" | 420 | "KernelPageSize: %8lu kB\n" |
420 | "MMUPageSize: %8lu kB\n", | 421 | "MMUPageSize: %8lu kB\n" |
422 | "Locked: %8lu kB\n", | ||
421 | (vma->vm_end - vma->vm_start) >> 10, | 423 | (vma->vm_end - vma->vm_start) >> 10, |
422 | mss.resident >> 10, | 424 | mss.resident >> 10, |
423 | (unsigned long)(mss.pss >> (10 + PSS_SHIFT)), | 425 | (unsigned long)(mss.pss >> (10 + PSS_SHIFT)), |
@@ -429,7 +431,9 @@ static int show_smap(struct seq_file *m, void *v) | |||
429 | mss.anonymous >> 10, | 431 | mss.anonymous >> 10, |
430 | mss.swap >> 10, | 432 | mss.swap >> 10, |
431 | vma_kernel_pagesize(vma) >> 10, | 433 | vma_kernel_pagesize(vma) >> 10, |
432 | vma_mmu_pagesize(vma) >> 10); | 434 | vma_mmu_pagesize(vma) >> 10, |
435 | (vma->vm_flags & VM_LOCKED) ? | ||
436 | (unsigned long)(mss.pss >> (10 + PSS_SHIFT)) : 0); | ||
433 | 437 | ||
434 | if (m->count < m->size) /* vma is copied successfully */ | 438 | if (m->count < m->size) /* vma is copied successfully */ |
435 | m->version = (vma != get_gate_vma(task)) ? vma->vm_start : 0; | 439 | m->version = (vma != get_gate_vma(task)) ? vma->vm_start : 0; |
diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c index cb6306e63843..b535d3e5d5f1 100644 --- a/fs/proc/task_nommu.c +++ b/fs/proc/task_nommu.c | |||
@@ -92,13 +92,14 @@ unsigned long task_vsize(struct mm_struct *mm) | |||
92 | return vsize; | 92 | return vsize; |
93 | } | 93 | } |
94 | 94 | ||
95 | int task_statm(struct mm_struct *mm, int *shared, int *text, | 95 | unsigned long task_statm(struct mm_struct *mm, |
96 | int *data, int *resident) | 96 | unsigned long *shared, unsigned long *text, |
97 | unsigned long *data, unsigned long *resident) | ||
97 | { | 98 | { |
98 | struct vm_area_struct *vma; | 99 | struct vm_area_struct *vma; |
99 | struct vm_region *region; | 100 | struct vm_region *region; |
100 | struct rb_node *p; | 101 | struct rb_node *p; |
101 | int size = kobjsize(mm); | 102 | unsigned long size = kobjsize(mm); |
102 | 103 | ||
103 | down_read(&mm->mmap_sem); | 104 | down_read(&mm->mmap_sem); |
104 | for (p = rb_first(&mm->mm_rb); p; p = rb_next(p)) { | 105 | for (p = rb_first(&mm->mm_rb); p; p = rb_next(p)) { |
diff --git a/fs/read_write.c b/fs/read_write.c index 5d431bacbea9..5520f8ad5504 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
@@ -30,18 +30,9 @@ const struct file_operations generic_ro_fops = { | |||
30 | 30 | ||
31 | EXPORT_SYMBOL(generic_ro_fops); | 31 | EXPORT_SYMBOL(generic_ro_fops); |
32 | 32 | ||
33 | static int | 33 | static inline int unsigned_offsets(struct file *file) |
34 | __negative_fpos_check(struct file *file, loff_t pos, size_t count) | ||
35 | { | 34 | { |
36 | /* | 35 | return file->f_mode & FMODE_UNSIGNED_OFFSET; |
37 | * pos or pos+count is negative here, check overflow. | ||
38 | * too big "count" will be caught in rw_verify_area(). | ||
39 | */ | ||
40 | if ((pos < 0) && (pos + count < pos)) | ||
41 | return -EOVERFLOW; | ||
42 | if (file->f_mode & FMODE_UNSIGNED_OFFSET) | ||
43 | return 0; | ||
44 | return -EINVAL; | ||
45 | } | 36 | } |
46 | 37 | ||
47 | /** | 38 | /** |
@@ -75,7 +66,7 @@ generic_file_llseek_unlocked(struct file *file, loff_t offset, int origin) | |||
75 | break; | 66 | break; |
76 | } | 67 | } |
77 | 68 | ||
78 | if (offset < 0 && __negative_fpos_check(file, offset, 0)) | 69 | if (offset < 0 && !unsigned_offsets(file)) |
79 | return -EINVAL; | 70 | return -EINVAL; |
80 | if (offset > inode->i_sb->s_maxbytes) | 71 | if (offset > inode->i_sb->s_maxbytes) |
81 | return -EINVAL; | 72 | return -EINVAL; |
@@ -152,7 +143,7 @@ loff_t default_llseek(struct file *file, loff_t offset, int origin) | |||
152 | offset += file->f_pos; | 143 | offset += file->f_pos; |
153 | } | 144 | } |
154 | retval = -EINVAL; | 145 | retval = -EINVAL; |
155 | if (offset >= 0 || !__negative_fpos_check(file, offset, 0)) { | 146 | if (offset >= 0 || unsigned_offsets(file)) { |
156 | if (offset != file->f_pos) { | 147 | if (offset != file->f_pos) { |
157 | file->f_pos = offset; | 148 | file->f_pos = offset; |
158 | file->f_version = 0; | 149 | file->f_version = 0; |
@@ -252,9 +243,13 @@ int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count | |||
252 | if (unlikely((ssize_t) count < 0)) | 243 | if (unlikely((ssize_t) count < 0)) |
253 | return retval; | 244 | return retval; |
254 | pos = *ppos; | 245 | pos = *ppos; |
255 | if (unlikely((pos < 0) || (loff_t) (pos + count) < 0)) { | 246 | if (unlikely(pos < 0)) { |
256 | retval = __negative_fpos_check(file, pos, count); | 247 | if (!unsigned_offsets(file)) |
257 | if (retval) | 248 | return retval; |
249 | if (count >= -pos) /* both values are in 0..LLONG_MAX */ | ||
250 | return -EOVERFLOW; | ||
251 | } else if (unlikely((loff_t) (pos + count) < 0)) { | ||
252 | if (!unsigned_offsets(file)) | ||
258 | return retval; | 253 | return retval; |
259 | } | 254 | } |
260 | 255 | ||
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index d31bce1a9f90..3eea859e6990 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c | |||
@@ -2551,8 +2551,6 @@ static int release_journal_dev(struct super_block *super, | |||
2551 | result = 0; | 2551 | result = 0; |
2552 | 2552 | ||
2553 | if (journal->j_dev_bd != NULL) { | 2553 | if (journal->j_dev_bd != NULL) { |
2554 | if (journal->j_dev_bd->bd_dev != super->s_dev) | ||
2555 | bd_release(journal->j_dev_bd); | ||
2556 | result = blkdev_put(journal->j_dev_bd, journal->j_dev_mode); | 2554 | result = blkdev_put(journal->j_dev_bd, journal->j_dev_mode); |
2557 | journal->j_dev_bd = NULL; | 2555 | journal->j_dev_bd = NULL; |
2558 | } | 2556 | } |
@@ -2570,7 +2568,7 @@ static int journal_init_dev(struct super_block *super, | |||
2570 | { | 2568 | { |
2571 | int result; | 2569 | int result; |
2572 | dev_t jdev; | 2570 | dev_t jdev; |
2573 | fmode_t blkdev_mode = FMODE_READ | FMODE_WRITE; | 2571 | fmode_t blkdev_mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL; |
2574 | char b[BDEVNAME_SIZE]; | 2572 | char b[BDEVNAME_SIZE]; |
2575 | 2573 | ||
2576 | result = 0; | 2574 | result = 0; |
@@ -2584,7 +2582,10 @@ static int journal_init_dev(struct super_block *super, | |||
2584 | 2582 | ||
2585 | /* there is no "jdev" option and journal is on separate device */ | 2583 | /* there is no "jdev" option and journal is on separate device */ |
2586 | if ((!jdev_name || !jdev_name[0])) { | 2584 | if ((!jdev_name || !jdev_name[0])) { |
2587 | journal->j_dev_bd = open_by_devnum(jdev, blkdev_mode); | 2585 | if (jdev == super->s_dev) |
2586 | blkdev_mode &= ~FMODE_EXCL; | ||
2587 | journal->j_dev_bd = blkdev_get_by_dev(jdev, blkdev_mode, | ||
2588 | journal); | ||
2588 | journal->j_dev_mode = blkdev_mode; | 2589 | journal->j_dev_mode = blkdev_mode; |
2589 | if (IS_ERR(journal->j_dev_bd)) { | 2590 | if (IS_ERR(journal->j_dev_bd)) { |
2590 | result = PTR_ERR(journal->j_dev_bd); | 2591 | result = PTR_ERR(journal->j_dev_bd); |
@@ -2593,22 +2594,14 @@ static int journal_init_dev(struct super_block *super, | |||
2593 | "cannot init journal device '%s': %i", | 2594 | "cannot init journal device '%s': %i", |
2594 | __bdevname(jdev, b), result); | 2595 | __bdevname(jdev, b), result); |
2595 | return result; | 2596 | return result; |
2596 | } else if (jdev != super->s_dev) { | 2597 | } else if (jdev != super->s_dev) |
2597 | result = bd_claim(journal->j_dev_bd, journal); | ||
2598 | if (result) { | ||
2599 | blkdev_put(journal->j_dev_bd, blkdev_mode); | ||
2600 | return result; | ||
2601 | } | ||
2602 | |||
2603 | set_blocksize(journal->j_dev_bd, super->s_blocksize); | 2598 | set_blocksize(journal->j_dev_bd, super->s_blocksize); |
2604 | } | ||
2605 | 2599 | ||
2606 | return 0; | 2600 | return 0; |
2607 | } | 2601 | } |
2608 | 2602 | ||
2609 | journal->j_dev_mode = blkdev_mode; | 2603 | journal->j_dev_mode = blkdev_mode; |
2610 | journal->j_dev_bd = open_bdev_exclusive(jdev_name, | 2604 | journal->j_dev_bd = blkdev_get_by_path(jdev_name, blkdev_mode, journal); |
2611 | blkdev_mode, journal); | ||
2612 | if (IS_ERR(journal->j_dev_bd)) { | 2605 | if (IS_ERR(journal->j_dev_bd)) { |
2613 | result = PTR_ERR(journal->j_dev_bd); | 2606 | result = PTR_ERR(journal->j_dev_bd); |
2614 | journal->j_dev_bd = NULL; | 2607 | journal->j_dev_bd = NULL; |
diff --git a/fs/reiserfs/prints.c b/fs/reiserfs/prints.c index adbc6f538515..45de98b59466 100644 --- a/fs/reiserfs/prints.c +++ b/fs/reiserfs/prints.c | |||
@@ -586,13 +586,13 @@ void print_block(struct buffer_head *bh, ...) //int print_mode, int first, int l | |||
586 | va_list args; | 586 | va_list args; |
587 | int mode, first, last; | 587 | int mode, first, last; |
588 | 588 | ||
589 | va_start(args, bh); | ||
590 | |||
591 | if (!bh) { | 589 | if (!bh) { |
592 | printk("print_block: buffer is NULL\n"); | 590 | printk("print_block: buffer is NULL\n"); |
593 | return; | 591 | return; |
594 | } | 592 | } |
595 | 593 | ||
594 | va_start(args, bh); | ||
595 | |||
596 | mode = va_arg(args, int); | 596 | mode = va_arg(args, int); |
597 | first = va_arg(args, int); | 597 | first = va_arg(args, int); |
598 | last = va_arg(args, int); | 598 | last = va_arg(args, int); |
diff --git a/fs/select.c b/fs/select.c index b7b10aa30861..e56560d2b08a 100644 --- a/fs/select.c +++ b/fs/select.c | |||
@@ -306,6 +306,8 @@ static int poll_select_copy_remaining(struct timespec *end_time, void __user *p, | |||
306 | rts.tv_sec = rts.tv_nsec = 0; | 306 | rts.tv_sec = rts.tv_nsec = 0; |
307 | 307 | ||
308 | if (timeval) { | 308 | if (timeval) { |
309 | if (sizeof(rtv) > sizeof(rtv.tv_sec) + sizeof(rtv.tv_usec)) | ||
310 | memset(&rtv, 0, sizeof(rtv)); | ||
309 | rtv.tv_sec = rts.tv_sec; | 311 | rtv.tv_sec = rts.tv_sec; |
310 | rtv.tv_usec = rts.tv_nsec / NSEC_PER_USEC; | 312 | rtv.tv_usec = rts.tv_nsec / NSEC_PER_USEC; |
311 | 313 | ||
diff --git a/fs/splice.c b/fs/splice.c index ce2f02579e35..50a5d978da16 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -682,19 +682,14 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe, | |||
682 | { | 682 | { |
683 | struct file *file = sd->u.file; | 683 | struct file *file = sd->u.file; |
684 | loff_t pos = sd->pos; | 684 | loff_t pos = sd->pos; |
685 | int ret, more; | 685 | int more; |
686 | |||
687 | ret = buf->ops->confirm(pipe, buf); | ||
688 | if (!ret) { | ||
689 | more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len; | ||
690 | if (file->f_op && file->f_op->sendpage) | ||
691 | ret = file->f_op->sendpage(file, buf->page, buf->offset, | ||
692 | sd->len, &pos, more); | ||
693 | else | ||
694 | ret = -EINVAL; | ||
695 | } | ||
696 | 686 | ||
697 | return ret; | 687 | if (!likely(file->f_op && file->f_op->sendpage)) |
688 | return -EINVAL; | ||
689 | |||
690 | more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len; | ||
691 | return file->f_op->sendpage(file, buf->page, buf->offset, | ||
692 | sd->len, &pos, more); | ||
698 | } | 693 | } |
699 | 694 | ||
700 | /* | 695 | /* |
@@ -727,13 +722,6 @@ int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, | |||
727 | void *fsdata; | 722 | void *fsdata; |
728 | int ret; | 723 | int ret; |
729 | 724 | ||
730 | /* | ||
731 | * make sure the data in this buffer is uptodate | ||
732 | */ | ||
733 | ret = buf->ops->confirm(pipe, buf); | ||
734 | if (unlikely(ret)) | ||
735 | return ret; | ||
736 | |||
737 | offset = sd->pos & ~PAGE_CACHE_MASK; | 725 | offset = sd->pos & ~PAGE_CACHE_MASK; |
738 | 726 | ||
739 | this_len = sd->len; | 727 | this_len = sd->len; |
@@ -805,12 +793,17 @@ int splice_from_pipe_feed(struct pipe_inode_info *pipe, struct splice_desc *sd, | |||
805 | if (sd->len > sd->total_len) | 793 | if (sd->len > sd->total_len) |
806 | sd->len = sd->total_len; | 794 | sd->len = sd->total_len; |
807 | 795 | ||
808 | ret = actor(pipe, buf, sd); | 796 | ret = buf->ops->confirm(pipe, buf); |
809 | if (ret <= 0) { | 797 | if (unlikely(ret)) { |
810 | if (ret == -ENODATA) | 798 | if (ret == -ENODATA) |
811 | ret = 0; | 799 | ret = 0; |
812 | return ret; | 800 | return ret; |
813 | } | 801 | } |
802 | |||
803 | ret = actor(pipe, buf, sd); | ||
804 | if (ret <= 0) | ||
805 | return ret; | ||
806 | |||
814 | buf->offset += ret; | 807 | buf->offset += ret; |
815 | buf->len -= ret; | 808 | buf->len -= ret; |
816 | 809 | ||
@@ -1044,10 +1037,6 @@ static int write_pipe_buf(struct pipe_inode_info *pipe, struct pipe_buffer *buf, | |||
1044 | int ret; | 1037 | int ret; |
1045 | void *data; | 1038 | void *data; |
1046 | 1039 | ||
1047 | ret = buf->ops->confirm(pipe, buf); | ||
1048 | if (ret) | ||
1049 | return ret; | ||
1050 | |||
1051 | data = buf->ops->map(pipe, buf, 0); | 1040 | data = buf->ops->map(pipe, buf, 0); |
1052 | ret = kernel_write(sd->u.file, data + buf->offset, sd->len, sd->pos); | 1041 | ret = kernel_write(sd->u.file, data + buf->offset, sd->len, sd->pos); |
1053 | buf->ops->unmap(pipe, buf, data); | 1042 | buf->ops->unmap(pipe, buf, data); |
@@ -1495,10 +1484,6 @@ static int pipe_to_user(struct pipe_inode_info *pipe, struct pipe_buffer *buf, | |||
1495 | char *src; | 1484 | char *src; |
1496 | int ret; | 1485 | int ret; |
1497 | 1486 | ||
1498 | ret = buf->ops->confirm(pipe, buf); | ||
1499 | if (unlikely(ret)) | ||
1500 | return ret; | ||
1501 | |||
1502 | /* | 1487 | /* |
1503 | * See if we can use the atomic maps, by prefaulting in the | 1488 | * See if we can use the atomic maps, by prefaulting in the |
1504 | * pages and doing an atomic copy | 1489 | * pages and doing an atomic copy |
diff --git a/fs/super.c b/fs/super.c index 823e061faa87..4f6a3571a634 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -767,13 +767,13 @@ struct dentry *mount_bdev(struct file_system_type *fs_type, | |||
767 | { | 767 | { |
768 | struct block_device *bdev; | 768 | struct block_device *bdev; |
769 | struct super_block *s; | 769 | struct super_block *s; |
770 | fmode_t mode = FMODE_READ; | 770 | fmode_t mode = FMODE_READ | FMODE_EXCL; |
771 | int error = 0; | 771 | int error = 0; |
772 | 772 | ||
773 | if (!(flags & MS_RDONLY)) | 773 | if (!(flags & MS_RDONLY)) |
774 | mode |= FMODE_WRITE; | 774 | mode |= FMODE_WRITE; |
775 | 775 | ||
776 | bdev = open_bdev_exclusive(dev_name, mode, fs_type); | 776 | bdev = blkdev_get_by_path(dev_name, mode, fs_type); |
777 | if (IS_ERR(bdev)) | 777 | if (IS_ERR(bdev)) |
778 | return ERR_CAST(bdev); | 778 | return ERR_CAST(bdev); |
779 | 779 | ||
@@ -802,13 +802,13 @@ struct dentry *mount_bdev(struct file_system_type *fs_type, | |||
802 | 802 | ||
803 | /* | 803 | /* |
804 | * s_umount nests inside bd_mutex during | 804 | * s_umount nests inside bd_mutex during |
805 | * __invalidate_device(). close_bdev_exclusive() | 805 | * __invalidate_device(). blkdev_put() acquires |
806 | * acquires bd_mutex and can't be called under | 806 | * bd_mutex and can't be called under s_umount. Drop |
807 | * s_umount. Drop s_umount temporarily. This is safe | 807 | * s_umount temporarily. This is safe as we're |
808 | * as we're holding an active reference. | 808 | * holding an active reference. |
809 | */ | 809 | */ |
810 | up_write(&s->s_umount); | 810 | up_write(&s->s_umount); |
811 | close_bdev_exclusive(bdev, mode); | 811 | blkdev_put(bdev, mode); |
812 | down_write(&s->s_umount); | 812 | down_write(&s->s_umount); |
813 | } else { | 813 | } else { |
814 | char b[BDEVNAME_SIZE]; | 814 | char b[BDEVNAME_SIZE]; |
@@ -832,7 +832,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type, | |||
832 | error_s: | 832 | error_s: |
833 | error = PTR_ERR(s); | 833 | error = PTR_ERR(s); |
834 | error_bdev: | 834 | error_bdev: |
835 | close_bdev_exclusive(bdev, mode); | 835 | blkdev_put(bdev, mode); |
836 | error: | 836 | error: |
837 | return ERR_PTR(error); | 837 | return ERR_PTR(error); |
838 | } | 838 | } |
@@ -863,7 +863,8 @@ void kill_block_super(struct super_block *sb) | |||
863 | bdev->bd_super = NULL; | 863 | bdev->bd_super = NULL; |
864 | generic_shutdown_super(sb); | 864 | generic_shutdown_super(sb); |
865 | sync_blockdev(bdev); | 865 | sync_blockdev(bdev); |
866 | close_bdev_exclusive(bdev, mode); | 866 | WARN_ON_ONCE(!(mode & FMODE_EXCL)); |
867 | blkdev_put(bdev, mode | FMODE_EXCL); | ||
867 | } | 868 | } |
868 | 869 | ||
869 | EXPORT_SYMBOL(kill_block_super); | 870 | EXPORT_SYMBOL(kill_block_super); |
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c index b5e68da2db32..b427b1208c26 100644 --- a/fs/sysv/namei.c +++ b/fs/sysv/namei.c | |||
@@ -48,7 +48,6 @@ static struct dentry *sysv_lookup(struct inode * dir, struct dentry * dentry, st | |||
48 | struct inode * inode = NULL; | 48 | struct inode * inode = NULL; |
49 | ino_t ino; | 49 | ino_t ino; |
50 | 50 | ||
51 | d_set_d_op(dentry, dir->i_sb->s_root->d_op); | ||
52 | if (dentry->d_name.len > SYSV_NAMELEN) | 51 | if (dentry->d_name.len > SYSV_NAMELEN) |
53 | return ERR_PTR(-ENAMETOOLONG); | 52 | return ERR_PTR(-ENAMETOOLONG); |
54 | ino = sysv_inode_by_name(dentry); | 53 | ino = sysv_inode_by_name(dentry); |
diff --git a/fs/sysv/super.c b/fs/sysv/super.c index 76712aefc4ab..f60c196913ea 100644 --- a/fs/sysv/super.c +++ b/fs/sysv/super.c | |||
@@ -332,6 +332,10 @@ static int complete_read_super(struct super_block *sb, int silent, int size) | |||
332 | sb->s_magic = SYSV_MAGIC_BASE + sbi->s_type; | 332 | sb->s_magic = SYSV_MAGIC_BASE + sbi->s_type; |
333 | /* set up enough so that it can read an inode */ | 333 | /* set up enough so that it can read an inode */ |
334 | sb->s_op = &sysv_sops; | 334 | sb->s_op = &sysv_sops; |
335 | if (sbi->s_forced_ro) | ||
336 | sb->s_flags |= MS_RDONLY; | ||
337 | if (sbi->s_truncate) | ||
338 | sb->s_d_op = &sysv_dentry_operations; | ||
335 | root_inode = sysv_iget(sb, SYSV_ROOT_INO); | 339 | root_inode = sysv_iget(sb, SYSV_ROOT_INO); |
336 | if (IS_ERR(root_inode)) { | 340 | if (IS_ERR(root_inode)) { |
337 | printk("SysV FS: get root inode failed\n"); | 341 | printk("SysV FS: get root inode failed\n"); |
@@ -343,10 +347,6 @@ static int complete_read_super(struct super_block *sb, int silent, int size) | |||
343 | printk("SysV FS: get root dentry failed\n"); | 347 | printk("SysV FS: get root dentry failed\n"); |
344 | return 0; | 348 | return 0; |
345 | } | 349 | } |
346 | if (sbi->s_forced_ro) | ||
347 | sb->s_flags |= MS_RDONLY; | ||
348 | if (sbi->s_truncate) | ||
349 | d_set_d_op(sb->s_root, &sysv_dentry_operations); | ||
350 | return 1; | 350 | return 1; |
351 | } | 351 | } |
352 | 352 | ||
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 94d5fd6a2973..da54403633b6 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
@@ -516,6 +516,7 @@ xfs_vn_fallocate( | |||
516 | loff_t new_size = 0; | 516 | loff_t new_size = 0; |
517 | xfs_flock64_t bf; | 517 | xfs_flock64_t bf; |
518 | xfs_inode_t *ip = XFS_I(inode); | 518 | xfs_inode_t *ip = XFS_I(inode); |
519 | int cmd = XFS_IOC_RESVSP; | ||
519 | 520 | ||
520 | /* preallocation on directories not yet supported */ | 521 | /* preallocation on directories not yet supported */ |
521 | error = -ENODEV; | 522 | error = -ENODEV; |
@@ -528,6 +529,9 @@ xfs_vn_fallocate( | |||
528 | 529 | ||
529 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | 530 | xfs_ilock(ip, XFS_IOLOCK_EXCL); |
530 | 531 | ||
532 | if (mode & FALLOC_FL_PUNCH_HOLE) | ||
533 | cmd = XFS_IOC_UNRESVSP; | ||
534 | |||
531 | /* check the new inode size is valid before allocating */ | 535 | /* check the new inode size is valid before allocating */ |
532 | if (!(mode & FALLOC_FL_KEEP_SIZE) && | 536 | if (!(mode & FALLOC_FL_KEEP_SIZE) && |
533 | offset + len > i_size_read(inode)) { | 537 | offset + len > i_size_read(inode)) { |
@@ -537,8 +541,7 @@ xfs_vn_fallocate( | |||
537 | goto out_unlock; | 541 | goto out_unlock; |
538 | } | 542 | } |
539 | 543 | ||
540 | error = -xfs_change_file_space(ip, XFS_IOC_RESVSP, &bf, | 544 | error = -xfs_change_file_space(ip, cmd, &bf, 0, XFS_ATTR_NOLOCK); |
541 | 0, XFS_ATTR_NOLOCK); | ||
542 | if (error) | 545 | if (error) |
543 | goto out_unlock; | 546 | goto out_unlock; |
544 | 547 | ||
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index c51faaa5e291..bd07f7339366 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -606,7 +606,8 @@ xfs_blkdev_get( | |||
606 | { | 606 | { |
607 | int error = 0; | 607 | int error = 0; |
608 | 608 | ||
609 | *bdevp = open_bdev_exclusive(name, FMODE_READ|FMODE_WRITE, mp); | 609 | *bdevp = blkdev_get_by_path(name, FMODE_READ|FMODE_WRITE|FMODE_EXCL, |
610 | mp); | ||
610 | if (IS_ERR(*bdevp)) { | 611 | if (IS_ERR(*bdevp)) { |
611 | error = PTR_ERR(*bdevp); | 612 | error = PTR_ERR(*bdevp); |
612 | printk("XFS: Invalid device [%s], error=%d\n", name, error); | 613 | printk("XFS: Invalid device [%s], error=%d\n", name, error); |
@@ -620,7 +621,7 @@ xfs_blkdev_put( | |||
620 | struct block_device *bdev) | 621 | struct block_device *bdev) |
621 | { | 622 | { |
622 | if (bdev) | 623 | if (bdev) |
623 | close_bdev_exclusive(bdev, FMODE_READ|FMODE_WRITE); | 624 | blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); |
624 | } | 625 | } |
625 | 626 | ||
626 | /* | 627 | /* |
@@ -947,7 +948,7 @@ out_reclaim: | |||
947 | * Slab object creation initialisation for the XFS inode. | 948 | * Slab object creation initialisation for the XFS inode. |
948 | * This covers only the idempotent fields in the XFS inode; | 949 | * This covers only the idempotent fields in the XFS inode; |
949 | * all other fields need to be initialised on allocation | 950 | * all other fields need to be initialised on allocation |
950 | * from the slab. This avoids the need to repeatedly intialise | 951 | * from the slab. This avoids the need to repeatedly initialise |
951 | * fields in the xfs inode that left in the initialise state | 952 | * fields in the xfs inode that left in the initialise state |
952 | * when freeing the inode. | 953 | * when freeing the inode. |
953 | */ | 954 | */ |