diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/afs/dir.c | 8 | ||||
-rw-r--r-- | fs/afs/fsclient.c | 3 | ||||
-rw-r--r-- | fs/afs/inode.c | 10 | ||||
-rw-r--r-- | fs/afs/super.c | 74 | ||||
-rw-r--r-- | fs/afs/write.c | 21 | ||||
-rw-r--r-- | fs/buffer.c | 4 | ||||
-rw-r--r-- | fs/cifs/cache.c | 6 | ||||
-rw-r--r-- | fs/cifs/cifsfs.c | 33 | ||||
-rw-r--r-- | fs/cifs/cifsfs.h | 2 | ||||
-rw-r--r-- | fs/cifs/connect.c | 23 | ||||
-rw-r--r-- | fs/cifs/fscache.c | 51 | ||||
-rw-r--r-- | fs/namei.c | 28 | ||||
-rw-r--r-- | fs/proc/root.c | 11 | ||||
-rw-r--r-- | fs/sysfs/mount.c | 37 | ||||
-rw-r--r-- | fs/sysfs/sysfs.h | 2 | ||||
-rw-r--r-- | fs/ubifs/super.c | 137 |
16 files changed, 240 insertions, 210 deletions
diff --git a/fs/afs/dir.c b/fs/afs/dir.c index 20c106f24927..1b0b19550015 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c | |||
@@ -584,11 +584,11 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, | |||
584 | 584 | ||
585 | success: | 585 | success: |
586 | d_add(dentry, inode); | 586 | d_add(dentry, inode); |
587 | _leave(" = 0 { vn=%u u=%u } -> { ino=%lu v=%llu }", | 587 | _leave(" = 0 { vn=%u u=%u } -> { ino=%lu v=%u }", |
588 | fid.vnode, | 588 | fid.vnode, |
589 | fid.unique, | 589 | fid.unique, |
590 | dentry->d_inode->i_ino, | 590 | dentry->d_inode->i_ino, |
591 | (unsigned long long)dentry->d_inode->i_version); | 591 | dentry->d_inode->i_generation); |
592 | 592 | ||
593 | return NULL; | 593 | return NULL; |
594 | } | 594 | } |
@@ -671,10 +671,10 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
671 | * been deleted and replaced, and the original vnode ID has | 671 | * been deleted and replaced, and the original vnode ID has |
672 | * been reused */ | 672 | * been reused */ |
673 | if (fid.unique != vnode->fid.unique) { | 673 | if (fid.unique != vnode->fid.unique) { |
674 | _debug("%s: file deleted (uq %u -> %u I:%llu)", | 674 | _debug("%s: file deleted (uq %u -> %u I:%u)", |
675 | dentry->d_name.name, fid.unique, | 675 | dentry->d_name.name, fid.unique, |
676 | vnode->fid.unique, | 676 | vnode->fid.unique, |
677 | (unsigned long long)dentry->d_inode->i_version); | 677 | dentry->d_inode->i_generation); |
678 | spin_lock(&vnode->lock); | 678 | spin_lock(&vnode->lock); |
679 | set_bit(AFS_VNODE_DELETED, &vnode->flags); | 679 | set_bit(AFS_VNODE_DELETED, &vnode->flags); |
680 | spin_unlock(&vnode->lock); | 680 | spin_unlock(&vnode->lock); |
diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c index 4bd0218473a9..346e3289abd7 100644 --- a/fs/afs/fsclient.c +++ b/fs/afs/fsclient.c | |||
@@ -89,7 +89,7 @@ static void xdr_decode_AFSFetchStatus(const __be32 **_bp, | |||
89 | i_size_write(&vnode->vfs_inode, size); | 89 | i_size_write(&vnode->vfs_inode, size); |
90 | vnode->vfs_inode.i_uid = status->owner; | 90 | vnode->vfs_inode.i_uid = status->owner; |
91 | vnode->vfs_inode.i_gid = status->group; | 91 | vnode->vfs_inode.i_gid = status->group; |
92 | vnode->vfs_inode.i_version = vnode->fid.unique; | 92 | vnode->vfs_inode.i_generation = vnode->fid.unique; |
93 | vnode->vfs_inode.i_nlink = status->nlink; | 93 | vnode->vfs_inode.i_nlink = status->nlink; |
94 | 94 | ||
95 | mode = vnode->vfs_inode.i_mode; | 95 | mode = vnode->vfs_inode.i_mode; |
@@ -102,6 +102,7 @@ static void xdr_decode_AFSFetchStatus(const __be32 **_bp, | |||
102 | vnode->vfs_inode.i_ctime.tv_sec = status->mtime_server; | 102 | vnode->vfs_inode.i_ctime.tv_sec = status->mtime_server; |
103 | vnode->vfs_inode.i_mtime = vnode->vfs_inode.i_ctime; | 103 | vnode->vfs_inode.i_mtime = vnode->vfs_inode.i_ctime; |
104 | vnode->vfs_inode.i_atime = vnode->vfs_inode.i_ctime; | 104 | vnode->vfs_inode.i_atime = vnode->vfs_inode.i_ctime; |
105 | vnode->vfs_inode.i_version = data_version; | ||
105 | } | 106 | } |
106 | 107 | ||
107 | expected_version = status->data_version; | 108 | expected_version = status->data_version; |
diff --git a/fs/afs/inode.c b/fs/afs/inode.c index db66c5201474..0fdab6e03d87 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c | |||
@@ -75,7 +75,8 @@ static int afs_inode_map_status(struct afs_vnode *vnode, struct key *key) | |||
75 | inode->i_ctime.tv_nsec = 0; | 75 | inode->i_ctime.tv_nsec = 0; |
76 | inode->i_atime = inode->i_mtime = inode->i_ctime; | 76 | inode->i_atime = inode->i_mtime = inode->i_ctime; |
77 | inode->i_blocks = 0; | 77 | inode->i_blocks = 0; |
78 | inode->i_version = vnode->fid.unique; | 78 | inode->i_generation = vnode->fid.unique; |
79 | inode->i_version = vnode->status.data_version; | ||
79 | inode->i_mapping->a_ops = &afs_fs_aops; | 80 | inode->i_mapping->a_ops = &afs_fs_aops; |
80 | 81 | ||
81 | /* check to see whether a symbolic link is really a mountpoint */ | 82 | /* check to see whether a symbolic link is really a mountpoint */ |
@@ -100,7 +101,7 @@ static int afs_iget5_test(struct inode *inode, void *opaque) | |||
100 | struct afs_iget_data *data = opaque; | 101 | struct afs_iget_data *data = opaque; |
101 | 102 | ||
102 | return inode->i_ino == data->fid.vnode && | 103 | return inode->i_ino == data->fid.vnode && |
103 | inode->i_version == data->fid.unique; | 104 | inode->i_generation == data->fid.unique; |
104 | } | 105 | } |
105 | 106 | ||
106 | /* | 107 | /* |
@@ -122,7 +123,7 @@ static int afs_iget5_set(struct inode *inode, void *opaque) | |||
122 | struct afs_vnode *vnode = AFS_FS_I(inode); | 123 | struct afs_vnode *vnode = AFS_FS_I(inode); |
123 | 124 | ||
124 | inode->i_ino = data->fid.vnode; | 125 | inode->i_ino = data->fid.vnode; |
125 | inode->i_version = data->fid.unique; | 126 | inode->i_generation = data->fid.unique; |
126 | vnode->fid = data->fid; | 127 | vnode->fid = data->fid; |
127 | vnode->volume = data->volume; | 128 | vnode->volume = data->volume; |
128 | 129 | ||
@@ -380,8 +381,7 @@ int afs_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
380 | 381 | ||
381 | inode = dentry->d_inode; | 382 | inode = dentry->d_inode; |
382 | 383 | ||
383 | _enter("{ ino=%lu v=%llu }", inode->i_ino, | 384 | _enter("{ ino=%lu v=%u }", inode->i_ino, inode->i_generation); |
384 | (unsigned long long)inode->i_version); | ||
385 | 385 | ||
386 | generic_fillattr(inode, stat); | 386 | generic_fillattr(inode, stat); |
387 | return 0; | 387 | return 0; |
diff --git a/fs/afs/super.c b/fs/afs/super.c index fb240e8766d6..356dcf0929e8 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c | |||
@@ -31,8 +31,8 @@ | |||
31 | static void afs_i_init_once(void *foo); | 31 | static void afs_i_init_once(void *foo); |
32 | static struct dentry *afs_mount(struct file_system_type *fs_type, | 32 | static struct dentry *afs_mount(struct file_system_type *fs_type, |
33 | int flags, const char *dev_name, void *data); | 33 | int flags, const char *dev_name, void *data); |
34 | static void afs_kill_super(struct super_block *sb); | ||
34 | static struct inode *afs_alloc_inode(struct super_block *sb); | 35 | static struct inode *afs_alloc_inode(struct super_block *sb); |
35 | static void afs_put_super(struct super_block *sb); | ||
36 | static void afs_destroy_inode(struct inode *inode); | 36 | static void afs_destroy_inode(struct inode *inode); |
37 | static int afs_statfs(struct dentry *dentry, struct kstatfs *buf); | 37 | static int afs_statfs(struct dentry *dentry, struct kstatfs *buf); |
38 | 38 | ||
@@ -40,7 +40,7 @@ struct file_system_type afs_fs_type = { | |||
40 | .owner = THIS_MODULE, | 40 | .owner = THIS_MODULE, |
41 | .name = "afs", | 41 | .name = "afs", |
42 | .mount = afs_mount, | 42 | .mount = afs_mount, |
43 | .kill_sb = kill_anon_super, | 43 | .kill_sb = afs_kill_super, |
44 | .fs_flags = 0, | 44 | .fs_flags = 0, |
45 | }; | 45 | }; |
46 | 46 | ||
@@ -50,7 +50,6 @@ static const struct super_operations afs_super_ops = { | |||
50 | .drop_inode = afs_drop_inode, | 50 | .drop_inode = afs_drop_inode, |
51 | .destroy_inode = afs_destroy_inode, | 51 | .destroy_inode = afs_destroy_inode, |
52 | .evict_inode = afs_evict_inode, | 52 | .evict_inode = afs_evict_inode, |
53 | .put_super = afs_put_super, | ||
54 | .show_options = generic_show_options, | 53 | .show_options = generic_show_options, |
55 | }; | 54 | }; |
56 | 55 | ||
@@ -282,19 +281,25 @@ static int afs_parse_device_name(struct afs_mount_params *params, | |||
282 | */ | 281 | */ |
283 | static int afs_test_super(struct super_block *sb, void *data) | 282 | static int afs_test_super(struct super_block *sb, void *data) |
284 | { | 283 | { |
285 | struct afs_mount_params *params = data; | 284 | struct afs_super_info *as1 = data; |
286 | struct afs_super_info *as = sb->s_fs_info; | 285 | struct afs_super_info *as = sb->s_fs_info; |
287 | 286 | ||
288 | return as->volume == params->volume; | 287 | return as->volume == as1->volume; |
288 | } | ||
289 | |||
290 | static int afs_set_super(struct super_block *sb, void *data) | ||
291 | { | ||
292 | sb->s_fs_info = data; | ||
293 | return set_anon_super(sb, NULL); | ||
289 | } | 294 | } |
290 | 295 | ||
291 | /* | 296 | /* |
292 | * fill in the superblock | 297 | * fill in the superblock |
293 | */ | 298 | */ |
294 | static int afs_fill_super(struct super_block *sb, void *data) | 299 | static int afs_fill_super(struct super_block *sb, |
300 | struct afs_mount_params *params) | ||
295 | { | 301 | { |
296 | struct afs_mount_params *params = data; | 302 | struct afs_super_info *as = sb->s_fs_info; |
297 | struct afs_super_info *as = NULL; | ||
298 | struct afs_fid fid; | 303 | struct afs_fid fid; |
299 | struct dentry *root = NULL; | 304 | struct dentry *root = NULL; |
300 | struct inode *inode = NULL; | 305 | struct inode *inode = NULL; |
@@ -302,23 +307,13 @@ static int afs_fill_super(struct super_block *sb, void *data) | |||
302 | 307 | ||
303 | _enter(""); | 308 | _enter(""); |
304 | 309 | ||
305 | /* allocate a superblock info record */ | ||
306 | as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL); | ||
307 | if (!as) { | ||
308 | _leave(" = -ENOMEM"); | ||
309 | return -ENOMEM; | ||
310 | } | ||
311 | |||
312 | afs_get_volume(params->volume); | ||
313 | as->volume = params->volume; | ||
314 | |||
315 | /* fill in the superblock */ | 310 | /* fill in the superblock */ |
316 | sb->s_blocksize = PAGE_CACHE_SIZE; | 311 | sb->s_blocksize = PAGE_CACHE_SIZE; |
317 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; | 312 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; |
318 | sb->s_magic = AFS_FS_MAGIC; | 313 | sb->s_magic = AFS_FS_MAGIC; |
319 | sb->s_op = &afs_super_ops; | 314 | sb->s_op = &afs_super_ops; |
320 | sb->s_fs_info = as; | ||
321 | sb->s_bdi = &as->volume->bdi; | 315 | sb->s_bdi = &as->volume->bdi; |
316 | strlcpy(sb->s_id, as->volume->vlocation->vldb.name, sizeof(sb->s_id)); | ||
322 | 317 | ||
323 | /* allocate the root inode and dentry */ | 318 | /* allocate the root inode and dentry */ |
324 | fid.vid = as->volume->vid; | 319 | fid.vid = as->volume->vid; |
@@ -326,7 +321,7 @@ static int afs_fill_super(struct super_block *sb, void *data) | |||
326 | fid.unique = 1; | 321 | fid.unique = 1; |
327 | inode = afs_iget(sb, params->key, &fid, NULL, NULL); | 322 | inode = afs_iget(sb, params->key, &fid, NULL, NULL); |
328 | if (IS_ERR(inode)) | 323 | if (IS_ERR(inode)) |
329 | goto error_inode; | 324 | return PTR_ERR(inode); |
330 | 325 | ||
331 | if (params->autocell) | 326 | if (params->autocell) |
332 | set_bit(AFS_VNODE_AUTOCELL, &AFS_FS_I(inode)->flags); | 327 | set_bit(AFS_VNODE_AUTOCELL, &AFS_FS_I(inode)->flags); |
@@ -342,16 +337,8 @@ static int afs_fill_super(struct super_block *sb, void *data) | |||
342 | _leave(" = 0"); | 337 | _leave(" = 0"); |
343 | return 0; | 338 | return 0; |
344 | 339 | ||
345 | error_inode: | ||
346 | ret = PTR_ERR(inode); | ||
347 | inode = NULL; | ||
348 | error: | 340 | error: |
349 | iput(inode); | 341 | iput(inode); |
350 | afs_put_volume(as->volume); | ||
351 | kfree(as); | ||
352 | |||
353 | sb->s_fs_info = NULL; | ||
354 | |||
355 | _leave(" = %d", ret); | 342 | _leave(" = %d", ret); |
356 | return ret; | 343 | return ret; |
357 | } | 344 | } |
@@ -367,6 +354,7 @@ static struct dentry *afs_mount(struct file_system_type *fs_type, | |||
367 | struct afs_volume *vol; | 354 | struct afs_volume *vol; |
368 | struct key *key; | 355 | struct key *key; |
369 | char *new_opts = kstrdup(options, GFP_KERNEL); | 356 | char *new_opts = kstrdup(options, GFP_KERNEL); |
357 | struct afs_super_info *as; | ||
370 | int ret; | 358 | int ret; |
371 | 359 | ||
372 | _enter(",,%s,%p", dev_name, options); | 360 | _enter(",,%s,%p", dev_name, options); |
@@ -399,12 +387,22 @@ static struct dentry *afs_mount(struct file_system_type *fs_type, | |||
399 | ret = PTR_ERR(vol); | 387 | ret = PTR_ERR(vol); |
400 | goto error; | 388 | goto error; |
401 | } | 389 | } |
402 | params.volume = vol; | 390 | |
391 | /* allocate a superblock info record */ | ||
392 | as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL); | ||
393 | if (!as) { | ||
394 | ret = -ENOMEM; | ||
395 | afs_put_volume(vol); | ||
396 | goto error; | ||
397 | } | ||
398 | as->volume = vol; | ||
403 | 399 | ||
404 | /* allocate a deviceless superblock */ | 400 | /* allocate a deviceless superblock */ |
405 | sb = sget(fs_type, afs_test_super, set_anon_super, ¶ms); | 401 | sb = sget(fs_type, afs_test_super, afs_set_super, as); |
406 | if (IS_ERR(sb)) { | 402 | if (IS_ERR(sb)) { |
407 | ret = PTR_ERR(sb); | 403 | ret = PTR_ERR(sb); |
404 | afs_put_volume(vol); | ||
405 | kfree(as); | ||
408 | goto error; | 406 | goto error; |
409 | } | 407 | } |
410 | 408 | ||
@@ -422,16 +420,16 @@ static struct dentry *afs_mount(struct file_system_type *fs_type, | |||
422 | } else { | 420 | } else { |
423 | _debug("reuse"); | 421 | _debug("reuse"); |
424 | ASSERTCMP(sb->s_flags, &, MS_ACTIVE); | 422 | ASSERTCMP(sb->s_flags, &, MS_ACTIVE); |
423 | afs_put_volume(vol); | ||
424 | kfree(as); | ||
425 | } | 425 | } |
426 | 426 | ||
427 | afs_put_volume(params.volume); | ||
428 | afs_put_cell(params.cell); | 427 | afs_put_cell(params.cell); |
429 | kfree(new_opts); | 428 | kfree(new_opts); |
430 | _leave(" = 0 [%p]", sb); | 429 | _leave(" = 0 [%p]", sb); |
431 | return dget(sb->s_root); | 430 | return dget(sb->s_root); |
432 | 431 | ||
433 | error: | 432 | error: |
434 | afs_put_volume(params.volume); | ||
435 | afs_put_cell(params.cell); | 433 | afs_put_cell(params.cell); |
436 | key_put(params.key); | 434 | key_put(params.key); |
437 | kfree(new_opts); | 435 | kfree(new_opts); |
@@ -439,18 +437,12 @@ error: | |||
439 | return ERR_PTR(ret); | 437 | return ERR_PTR(ret); |
440 | } | 438 | } |
441 | 439 | ||
442 | /* | 440 | static void afs_kill_super(struct super_block *sb) |
443 | * finish the unmounting process on the superblock | ||
444 | */ | ||
445 | static void afs_put_super(struct super_block *sb) | ||
446 | { | 441 | { |
447 | struct afs_super_info *as = sb->s_fs_info; | 442 | struct afs_super_info *as = sb->s_fs_info; |
448 | 443 | kill_anon_super(sb); | |
449 | _enter(""); | ||
450 | |||
451 | afs_put_volume(as->volume); | 444 | afs_put_volume(as->volume); |
452 | 445 | kfree(as); | |
453 | _leave(""); | ||
454 | } | 446 | } |
455 | 447 | ||
456 | /* | 448 | /* |
diff --git a/fs/afs/write.c b/fs/afs/write.c index 789b3afb3423..b806285ff853 100644 --- a/fs/afs/write.c +++ b/fs/afs/write.c | |||
@@ -84,23 +84,21 @@ void afs_put_writeback(struct afs_writeback *wb) | |||
84 | * partly or wholly fill a page that's under preparation for writing | 84 | * partly or wholly fill a page that's under preparation for writing |
85 | */ | 85 | */ |
86 | static int afs_fill_page(struct afs_vnode *vnode, struct key *key, | 86 | static int afs_fill_page(struct afs_vnode *vnode, struct key *key, |
87 | loff_t pos, unsigned len, struct page *page) | 87 | loff_t pos, struct page *page) |
88 | { | 88 | { |
89 | loff_t i_size; | 89 | loff_t i_size; |
90 | unsigned eof; | ||
91 | int ret; | 90 | int ret; |
91 | int len; | ||
92 | 92 | ||
93 | _enter(",,%llu,%u", (unsigned long long)pos, len); | 93 | _enter(",,%llu", (unsigned long long)pos); |
94 | |||
95 | ASSERTCMP(len, <=, PAGE_CACHE_SIZE); | ||
96 | 94 | ||
97 | i_size = i_size_read(&vnode->vfs_inode); | 95 | i_size = i_size_read(&vnode->vfs_inode); |
98 | if (pos + len > i_size) | 96 | if (pos + PAGE_CACHE_SIZE > i_size) |
99 | eof = i_size; | 97 | len = i_size - pos; |
100 | else | 98 | else |
101 | eof = PAGE_CACHE_SIZE; | 99 | len = PAGE_CACHE_SIZE; |
102 | 100 | ||
103 | ret = afs_vnode_fetch_data(vnode, key, 0, eof, page); | 101 | ret = afs_vnode_fetch_data(vnode, key, pos, len, page); |
104 | if (ret < 0) { | 102 | if (ret < 0) { |
105 | if (ret == -ENOENT) { | 103 | if (ret == -ENOENT) { |
106 | _debug("got NOENT from server" | 104 | _debug("got NOENT from server" |
@@ -153,9 +151,8 @@ int afs_write_begin(struct file *file, struct address_space *mapping, | |||
153 | *pagep = page; | 151 | *pagep = page; |
154 | /* page won't leak in error case: it eventually gets cleaned off LRU */ | 152 | /* page won't leak in error case: it eventually gets cleaned off LRU */ |
155 | 153 | ||
156 | if (!PageUptodate(page)) { | 154 | if (!PageUptodate(page) && len != PAGE_CACHE_SIZE) { |
157 | _debug("not up to date"); | 155 | ret = afs_fill_page(vnode, key, index << PAGE_CACHE_SHIFT, page); |
158 | ret = afs_fill_page(vnode, key, pos, len, page); | ||
159 | if (ret < 0) { | 156 | if (ret < 0) { |
160 | kfree(candidate); | 157 | kfree(candidate); |
161 | _leave(" = %d [prep]", ret); | 158 | _leave(" = %d [prep]", ret); |
diff --git a/fs/buffer.c b/fs/buffer.c index 49c9aada0374..1a80b048ade8 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -1902,10 +1902,8 @@ int __block_write_begin(struct page *page, loff_t pos, unsigned len, | |||
1902 | if (!buffer_uptodate(*wait_bh)) | 1902 | if (!buffer_uptodate(*wait_bh)) |
1903 | err = -EIO; | 1903 | err = -EIO; |
1904 | } | 1904 | } |
1905 | if (unlikely(err)) { | 1905 | if (unlikely(err)) |
1906 | page_zero_new_buffers(page, from, to); | 1906 | page_zero_new_buffers(page, from, to); |
1907 | ClearPageUptodate(page); | ||
1908 | } | ||
1909 | return err; | 1907 | return err; |
1910 | } | 1908 | } |
1911 | EXPORT_SYMBOL(__block_write_begin); | 1909 | EXPORT_SYMBOL(__block_write_begin); |
diff --git a/fs/cifs/cache.c b/fs/cifs/cache.c index dd8584d35a14..545509c3313b 100644 --- a/fs/cifs/cache.c +++ b/fs/cifs/cache.c | |||
@@ -92,7 +92,7 @@ static uint16_t cifs_server_get_key(const void *cookie_netfs_data, | |||
92 | break; | 92 | break; |
93 | 93 | ||
94 | default: | 94 | default: |
95 | cERROR(1, "CIFS: Unknown network family '%d'", sa->sa_family); | 95 | cERROR(1, "Unknown network family '%d'", sa->sa_family); |
96 | key_len = 0; | 96 | key_len = 0; |
97 | break; | 97 | break; |
98 | } | 98 | } |
@@ -152,7 +152,7 @@ static uint16_t cifs_super_get_key(const void *cookie_netfs_data, void *buffer, | |||
152 | 152 | ||
153 | sharename = extract_sharename(tcon->treeName); | 153 | sharename = extract_sharename(tcon->treeName); |
154 | if (IS_ERR(sharename)) { | 154 | if (IS_ERR(sharename)) { |
155 | cFYI(1, "CIFS: couldn't extract sharename\n"); | 155 | cFYI(1, "%s: couldn't extract sharename\n", __func__); |
156 | sharename = NULL; | 156 | sharename = NULL; |
157 | return 0; | 157 | return 0; |
158 | } | 158 | } |
@@ -302,7 +302,7 @@ static void cifs_fscache_inode_now_uncached(void *cookie_netfs_data) | |||
302 | pagevec_init(&pvec, 0); | 302 | pagevec_init(&pvec, 0); |
303 | first = 0; | 303 | first = 0; |
304 | 304 | ||
305 | cFYI(1, "cifs inode 0x%p now uncached", cifsi); | 305 | cFYI(1, "%s: cifs inode 0x%p now uncached", __func__, cifsi); |
306 | 306 | ||
307 | for (;;) { | 307 | for (;;) { |
308 | nr_pages = pagevec_lookup(&pvec, | 308 | nr_pages = pagevec_lookup(&pvec, |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 989442dcfb45..e9def996e383 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -352,6 +352,37 @@ cifs_show_address(struct seq_file *s, struct TCP_Server_Info *server) | |||
352 | } | 352 | } |
353 | } | 353 | } |
354 | 354 | ||
355 | static void | ||
356 | cifs_show_security(struct seq_file *s, struct TCP_Server_Info *server) | ||
357 | { | ||
358 | seq_printf(s, ",sec="); | ||
359 | |||
360 | switch (server->secType) { | ||
361 | case LANMAN: | ||
362 | seq_printf(s, "lanman"); | ||
363 | break; | ||
364 | case NTLMv2: | ||
365 | seq_printf(s, "ntlmv2"); | ||
366 | break; | ||
367 | case NTLM: | ||
368 | seq_printf(s, "ntlm"); | ||
369 | break; | ||
370 | case Kerberos: | ||
371 | seq_printf(s, "krb5"); | ||
372 | break; | ||
373 | case RawNTLMSSP: | ||
374 | seq_printf(s, "ntlmssp"); | ||
375 | break; | ||
376 | default: | ||
377 | /* shouldn't ever happen */ | ||
378 | seq_printf(s, "unknown"); | ||
379 | break; | ||
380 | } | ||
381 | |||
382 | if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) | ||
383 | seq_printf(s, "i"); | ||
384 | } | ||
385 | |||
355 | /* | 386 | /* |
356 | * cifs_show_options() is for displaying mount options in /proc/mounts. | 387 | * cifs_show_options() is for displaying mount options in /proc/mounts. |
357 | * Not all settable options are displayed but most of the important | 388 | * Not all settable options are displayed but most of the important |
@@ -365,6 +396,8 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m) | |||
365 | struct sockaddr *srcaddr; | 396 | struct sockaddr *srcaddr; |
366 | srcaddr = (struct sockaddr *)&tcon->ses->server->srcaddr; | 397 | srcaddr = (struct sockaddr *)&tcon->ses->server->srcaddr; |
367 | 398 | ||
399 | cifs_show_security(s, tcon->ses->server); | ||
400 | |||
368 | seq_printf(s, ",unc=%s", tcon->treeName); | 401 | seq_printf(s, ",unc=%s", tcon->treeName); |
369 | 402 | ||
370 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) | 403 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 64313f778ebf..0900e1658c96 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
@@ -129,5 +129,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); | |||
129 | extern const struct export_operations cifs_export_ops; | 129 | extern const struct export_operations cifs_export_ops; |
130 | #endif /* CIFS_NFSD_EXPORT */ | 130 | #endif /* CIFS_NFSD_EXPORT */ |
131 | 131 | ||
132 | #define CIFS_VERSION "1.72" | 132 | #define CIFS_VERSION "1.73" |
133 | #endif /* _CIFSFS_H */ | 133 | #endif /* _CIFSFS_H */ |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index bb659eb73810..12cf72dd0c42 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -152,7 +152,7 @@ cifs_reconnect(struct TCP_Server_Info *server) | |||
152 | mid_entry->callback(mid_entry); | 152 | mid_entry->callback(mid_entry); |
153 | } | 153 | } |
154 | 154 | ||
155 | while (server->tcpStatus == CifsNeedReconnect) { | 155 | do { |
156 | try_to_freeze(); | 156 | try_to_freeze(); |
157 | 157 | ||
158 | /* we should try only the port we connected to before */ | 158 | /* we should try only the port we connected to before */ |
@@ -167,7 +167,7 @@ cifs_reconnect(struct TCP_Server_Info *server) | |||
167 | server->tcpStatus = CifsNeedNegotiate; | 167 | server->tcpStatus = CifsNeedNegotiate; |
168 | spin_unlock(&GlobalMid_Lock); | 168 | spin_unlock(&GlobalMid_Lock); |
169 | } | 169 | } |
170 | } | 170 | } while (server->tcpStatus == CifsNeedReconnect); |
171 | 171 | ||
172 | return rc; | 172 | return rc; |
173 | } | 173 | } |
@@ -2149,7 +2149,10 @@ cifs_put_tlink(struct tcon_link *tlink) | |||
2149 | } | 2149 | } |
2150 | 2150 | ||
2151 | static inline struct tcon_link * | 2151 | static inline struct tcon_link * |
2152 | cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb); | 2152 | cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb) |
2153 | { | ||
2154 | return cifs_sb->master_tlink; | ||
2155 | } | ||
2153 | 2156 | ||
2154 | static int | 2157 | static int |
2155 | compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data) | 2158 | compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data) |
@@ -3171,6 +3174,10 @@ out: | |||
3171 | return rc; | 3174 | return rc; |
3172 | } | 3175 | } |
3173 | 3176 | ||
3177 | /* | ||
3178 | * Issue a TREE_CONNECT request. Note that for IPC$ shares, that the tcon | ||
3179 | * pointer may be NULL. | ||
3180 | */ | ||
3174 | int | 3181 | int |
3175 | CIFSTCon(unsigned int xid, struct cifs_ses *ses, | 3182 | CIFSTCon(unsigned int xid, struct cifs_ses *ses, |
3176 | const char *tree, struct cifs_tcon *tcon, | 3183 | const char *tree, struct cifs_tcon *tcon, |
@@ -3205,7 +3212,7 @@ CIFSTCon(unsigned int xid, struct cifs_ses *ses, | |||
3205 | pSMB->AndXCommand = 0xFF; | 3212 | pSMB->AndXCommand = 0xFF; |
3206 | pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO); | 3213 | pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO); |
3207 | bcc_ptr = &pSMB->Password[0]; | 3214 | bcc_ptr = &pSMB->Password[0]; |
3208 | if ((ses->server->sec_mode) & SECMODE_USER) { | 3215 | if (!tcon || (ses->server->sec_mode & SECMODE_USER)) { |
3209 | pSMB->PasswordLength = cpu_to_le16(1); /* minimum */ | 3216 | pSMB->PasswordLength = cpu_to_le16(1); /* minimum */ |
3210 | *bcc_ptr = 0; /* password is null byte */ | 3217 | *bcc_ptr = 0; /* password is null byte */ |
3211 | bcc_ptr++; /* skip password */ | 3218 | bcc_ptr++; /* skip password */ |
@@ -3371,7 +3378,7 @@ int cifs_negotiate_protocol(unsigned int xid, struct cifs_ses *ses) | |||
3371 | } | 3378 | } |
3372 | if (rc == 0) { | 3379 | if (rc == 0) { |
3373 | spin_lock(&GlobalMid_Lock); | 3380 | spin_lock(&GlobalMid_Lock); |
3374 | if (server->tcpStatus != CifsExiting) | 3381 | if (server->tcpStatus == CifsNeedNegotiate) |
3375 | server->tcpStatus = CifsGood; | 3382 | server->tcpStatus = CifsGood; |
3376 | else | 3383 | else |
3377 | rc = -EHOSTDOWN; | 3384 | rc = -EHOSTDOWN; |
@@ -3484,12 +3491,6 @@ out: | |||
3484 | return tcon; | 3491 | return tcon; |
3485 | } | 3492 | } |
3486 | 3493 | ||
3487 | static inline struct tcon_link * | ||
3488 | cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb) | ||
3489 | { | ||
3490 | return cifs_sb->master_tlink; | ||
3491 | } | ||
3492 | |||
3493 | struct cifs_tcon * | 3494 | struct cifs_tcon * |
3494 | cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb) | 3495 | cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb) |
3495 | { | 3496 | { |
diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c index d368a47ba5eb..816696621ec9 100644 --- a/fs/cifs/fscache.c +++ b/fs/cifs/fscache.c | |||
@@ -28,14 +28,14 @@ void cifs_fscache_get_client_cookie(struct TCP_Server_Info *server) | |||
28 | server->fscache = | 28 | server->fscache = |
29 | fscache_acquire_cookie(cifs_fscache_netfs.primary_index, | 29 | fscache_acquire_cookie(cifs_fscache_netfs.primary_index, |
30 | &cifs_fscache_server_index_def, server); | 30 | &cifs_fscache_server_index_def, server); |
31 | cFYI(1, "CIFS: get client cookie (0x%p/0x%p)", server, | 31 | cFYI(1, "%s: (0x%p/0x%p)", __func__, server, |
32 | server->fscache); | 32 | server->fscache); |
33 | } | 33 | } |
34 | 34 | ||
35 | void cifs_fscache_release_client_cookie(struct TCP_Server_Info *server) | 35 | void cifs_fscache_release_client_cookie(struct TCP_Server_Info *server) |
36 | { | 36 | { |
37 | cFYI(1, "CIFS: release client cookie (0x%p/0x%p)", server, | 37 | cFYI(1, "%s: (0x%p/0x%p)", __func__, server, |
38 | server->fscache); | 38 | server->fscache); |
39 | fscache_relinquish_cookie(server->fscache, 0); | 39 | fscache_relinquish_cookie(server->fscache, 0); |
40 | server->fscache = NULL; | 40 | server->fscache = NULL; |
41 | } | 41 | } |
@@ -47,13 +47,13 @@ void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon) | |||
47 | tcon->fscache = | 47 | tcon->fscache = |
48 | fscache_acquire_cookie(server->fscache, | 48 | fscache_acquire_cookie(server->fscache, |
49 | &cifs_fscache_super_index_def, tcon); | 49 | &cifs_fscache_super_index_def, tcon); |
50 | cFYI(1, "CIFS: get superblock cookie (0x%p/0x%p)", | 50 | cFYI(1, "%s: (0x%p/0x%p)", __func__, server->fscache, |
51 | server->fscache, tcon->fscache); | 51 | tcon->fscache); |
52 | } | 52 | } |
53 | 53 | ||
54 | void cifs_fscache_release_super_cookie(struct cifs_tcon *tcon) | 54 | void cifs_fscache_release_super_cookie(struct cifs_tcon *tcon) |
55 | { | 55 | { |
56 | cFYI(1, "CIFS: releasing superblock cookie (0x%p)", tcon->fscache); | 56 | cFYI(1, "%s: (0x%p)", __func__, tcon->fscache); |
57 | fscache_relinquish_cookie(tcon->fscache, 0); | 57 | fscache_relinquish_cookie(tcon->fscache, 0); |
58 | tcon->fscache = NULL; | 58 | tcon->fscache = NULL; |
59 | } | 59 | } |
@@ -70,8 +70,8 @@ static void cifs_fscache_enable_inode_cookie(struct inode *inode) | |||
70 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE) { | 70 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE) { |
71 | cifsi->fscache = fscache_acquire_cookie(tcon->fscache, | 71 | cifsi->fscache = fscache_acquire_cookie(tcon->fscache, |
72 | &cifs_fscache_inode_object_def, cifsi); | 72 | &cifs_fscache_inode_object_def, cifsi); |
73 | cFYI(1, "CIFS: got FH cookie (0x%p/0x%p)", tcon->fscache, | 73 | cFYI(1, "%s: got FH cookie (0x%p/0x%p)", __func__, |
74 | cifsi->fscache); | 74 | tcon->fscache, cifsi->fscache); |
75 | } | 75 | } |
76 | } | 76 | } |
77 | 77 | ||
@@ -80,8 +80,7 @@ void cifs_fscache_release_inode_cookie(struct inode *inode) | |||
80 | struct cifsInodeInfo *cifsi = CIFS_I(inode); | 80 | struct cifsInodeInfo *cifsi = CIFS_I(inode); |
81 | 81 | ||
82 | if (cifsi->fscache) { | 82 | if (cifsi->fscache) { |
83 | cFYI(1, "CIFS releasing inode cookie (0x%p)", | 83 | cFYI(1, "%s: (0x%p)", __func__, cifsi->fscache); |
84 | cifsi->fscache); | ||
85 | fscache_relinquish_cookie(cifsi->fscache, 0); | 84 | fscache_relinquish_cookie(cifsi->fscache, 0); |
86 | cifsi->fscache = NULL; | 85 | cifsi->fscache = NULL; |
87 | } | 86 | } |
@@ -92,8 +91,7 @@ static void cifs_fscache_disable_inode_cookie(struct inode *inode) | |||
92 | struct cifsInodeInfo *cifsi = CIFS_I(inode); | 91 | struct cifsInodeInfo *cifsi = CIFS_I(inode); |
93 | 92 | ||
94 | if (cifsi->fscache) { | 93 | if (cifsi->fscache) { |
95 | cFYI(1, "CIFS disabling inode cookie (0x%p)", | 94 | cFYI(1, "%s: (0x%p)", __func__, cifsi->fscache); |
96 | cifsi->fscache); | ||
97 | fscache_relinquish_cookie(cifsi->fscache, 1); | 95 | fscache_relinquish_cookie(cifsi->fscache, 1); |
98 | cifsi->fscache = NULL; | 96 | cifsi->fscache = NULL; |
99 | } | 97 | } |
@@ -121,8 +119,8 @@ void cifs_fscache_reset_inode_cookie(struct inode *inode) | |||
121 | cifs_sb_master_tcon(cifs_sb)->fscache, | 119 | cifs_sb_master_tcon(cifs_sb)->fscache, |
122 | &cifs_fscache_inode_object_def, | 120 | &cifs_fscache_inode_object_def, |
123 | cifsi); | 121 | cifsi); |
124 | cFYI(1, "CIFS: new cookie 0x%p oldcookie 0x%p", | 122 | cFYI(1, "%s: new cookie 0x%p oldcookie 0x%p", |
125 | cifsi->fscache, old); | 123 | __func__, cifsi->fscache, old); |
126 | } | 124 | } |
127 | } | 125 | } |
128 | 126 | ||
@@ -132,8 +130,8 @@ int cifs_fscache_release_page(struct page *page, gfp_t gfp) | |||
132 | struct inode *inode = page->mapping->host; | 130 | struct inode *inode = page->mapping->host; |
133 | struct cifsInodeInfo *cifsi = CIFS_I(inode); | 131 | struct cifsInodeInfo *cifsi = CIFS_I(inode); |
134 | 132 | ||
135 | cFYI(1, "CIFS: fscache release page (0x%p/0x%p)", | 133 | cFYI(1, "%s: (0x%p/0x%p)", __func__, page, |
136 | page, cifsi->fscache); | 134 | cifsi->fscache); |
137 | if (!fscache_maybe_release_page(cifsi->fscache, page, gfp)) | 135 | if (!fscache_maybe_release_page(cifsi->fscache, page, gfp)) |
138 | return 0; | 136 | return 0; |
139 | } | 137 | } |
@@ -144,8 +142,7 @@ int cifs_fscache_release_page(struct page *page, gfp_t gfp) | |||
144 | static void cifs_readpage_from_fscache_complete(struct page *page, void *ctx, | 142 | static void cifs_readpage_from_fscache_complete(struct page *page, void *ctx, |
145 | int error) | 143 | int error) |
146 | { | 144 | { |
147 | cFYI(1, "CFS: readpage_from_fscache_complete (0x%p/%d)", | 145 | cFYI(1, "%s: (0x%p/%d)", __func__, page, error); |
148 | page, error); | ||
149 | if (!error) | 146 | if (!error) |
150 | SetPageUptodate(page); | 147 | SetPageUptodate(page); |
151 | unlock_page(page); | 148 | unlock_page(page); |
@@ -158,7 +155,7 @@ int __cifs_readpage_from_fscache(struct inode *inode, struct page *page) | |||
158 | { | 155 | { |
159 | int ret; | 156 | int ret; |
160 | 157 | ||
161 | cFYI(1, "CIFS: readpage_from_fscache(fsc:%p, p:%p, i:0x%p", | 158 | cFYI(1, "%s: (fsc:%p, p:%p, i:0x%p", __func__, |
162 | CIFS_I(inode)->fscache, page, inode); | 159 | CIFS_I(inode)->fscache, page, inode); |
163 | ret = fscache_read_or_alloc_page(CIFS_I(inode)->fscache, page, | 160 | ret = fscache_read_or_alloc_page(CIFS_I(inode)->fscache, page, |
164 | cifs_readpage_from_fscache_complete, | 161 | cifs_readpage_from_fscache_complete, |
@@ -167,11 +164,11 @@ int __cifs_readpage_from_fscache(struct inode *inode, struct page *page) | |||
167 | switch (ret) { | 164 | switch (ret) { |
168 | 165 | ||
169 | case 0: /* page found in fscache, read submitted */ | 166 | case 0: /* page found in fscache, read submitted */ |
170 | cFYI(1, "CIFS: readpage_from_fscache: submitted"); | 167 | cFYI(1, "%s: submitted", __func__); |
171 | return ret; | 168 | return ret; |
172 | case -ENOBUFS: /* page won't be cached */ | 169 | case -ENOBUFS: /* page won't be cached */ |
173 | case -ENODATA: /* page not in cache */ | 170 | case -ENODATA: /* page not in cache */ |
174 | cFYI(1, "CIFS: readpage_from_fscache %d", ret); | 171 | cFYI(1, "%s: %d", __func__, ret); |
175 | return 1; | 172 | return 1; |
176 | 173 | ||
177 | default: | 174 | default: |
@@ -190,7 +187,7 @@ int __cifs_readpages_from_fscache(struct inode *inode, | |||
190 | { | 187 | { |
191 | int ret; | 188 | int ret; |
192 | 189 | ||
193 | cFYI(1, "CIFS: __cifs_readpages_from_fscache (0x%p/%u/0x%p)", | 190 | cFYI(1, "%s: (0x%p/%u/0x%p)", __func__, |
194 | CIFS_I(inode)->fscache, *nr_pages, inode); | 191 | CIFS_I(inode)->fscache, *nr_pages, inode); |
195 | ret = fscache_read_or_alloc_pages(CIFS_I(inode)->fscache, mapping, | 192 | ret = fscache_read_or_alloc_pages(CIFS_I(inode)->fscache, mapping, |
196 | pages, nr_pages, | 193 | pages, nr_pages, |
@@ -199,12 +196,12 @@ int __cifs_readpages_from_fscache(struct inode *inode, | |||
199 | mapping_gfp_mask(mapping)); | 196 | mapping_gfp_mask(mapping)); |
200 | switch (ret) { | 197 | switch (ret) { |
201 | case 0: /* read submitted to the cache for all pages */ | 198 | case 0: /* read submitted to the cache for all pages */ |
202 | cFYI(1, "CIFS: readpages_from_fscache: submitted"); | 199 | cFYI(1, "%s: submitted", __func__); |
203 | return ret; | 200 | return ret; |
204 | 201 | ||
205 | case -ENOBUFS: /* some pages are not cached and can't be */ | 202 | case -ENOBUFS: /* some pages are not cached and can't be */ |
206 | case -ENODATA: /* some pages are not cached */ | 203 | case -ENODATA: /* some pages are not cached */ |
207 | cFYI(1, "CIFS: readpages_from_fscache: no page"); | 204 | cFYI(1, "%s: no page", __func__); |
208 | return 1; | 205 | return 1; |
209 | 206 | ||
210 | default: | 207 | default: |
@@ -218,7 +215,7 @@ void __cifs_readpage_to_fscache(struct inode *inode, struct page *page) | |||
218 | { | 215 | { |
219 | int ret; | 216 | int ret; |
220 | 217 | ||
221 | cFYI(1, "CIFS: readpage_to_fscache(fsc: %p, p: %p, i: %p", | 218 | cFYI(1, "%s: (fsc: %p, p: %p, i: %p)", __func__, |
222 | CIFS_I(inode)->fscache, page, inode); | 219 | CIFS_I(inode)->fscache, page, inode); |
223 | ret = fscache_write_page(CIFS_I(inode)->fscache, page, GFP_KERNEL); | 220 | ret = fscache_write_page(CIFS_I(inode)->fscache, page, GFP_KERNEL); |
224 | if (ret != 0) | 221 | if (ret != 0) |
@@ -230,7 +227,7 @@ void __cifs_fscache_invalidate_page(struct page *page, struct inode *inode) | |||
230 | struct cifsInodeInfo *cifsi = CIFS_I(inode); | 227 | struct cifsInodeInfo *cifsi = CIFS_I(inode); |
231 | struct fscache_cookie *cookie = cifsi->fscache; | 228 | struct fscache_cookie *cookie = cifsi->fscache; |
232 | 229 | ||
233 | cFYI(1, "CIFS: fscache invalidatepage (0x%p/0x%p)", page, cookie); | 230 | cFYI(1, "%s: (0x%p/0x%p)", __func__, page, cookie); |
234 | fscache_wait_on_page_write(cookie, page); | 231 | fscache_wait_on_page_write(cookie, page); |
235 | fscache_uncache_page(cookie, page); | 232 | fscache_uncache_page(cookie, page); |
236 | } | 233 | } |
diff --git a/fs/namei.c b/fs/namei.c index 9802345df5e7..9e425e7e6c8f 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -812,6 +812,11 @@ static int follow_automount(struct path *path, unsigned flags, | |||
812 | if (!mnt) /* mount collision */ | 812 | if (!mnt) /* mount collision */ |
813 | return 0; | 813 | return 0; |
814 | 814 | ||
815 | if (!*need_mntput) { | ||
816 | /* lock_mount() may release path->mnt on error */ | ||
817 | mntget(path->mnt); | ||
818 | *need_mntput = true; | ||
819 | } | ||
815 | err = finish_automount(mnt, path); | 820 | err = finish_automount(mnt, path); |
816 | 821 | ||
817 | switch (err) { | 822 | switch (err) { |
@@ -819,12 +824,9 @@ static int follow_automount(struct path *path, unsigned flags, | |||
819 | /* Someone else made a mount here whilst we were busy */ | 824 | /* Someone else made a mount here whilst we were busy */ |
820 | return 0; | 825 | return 0; |
821 | case 0: | 826 | case 0: |
822 | dput(path->dentry); | 827 | path_put(path); |
823 | if (*need_mntput) | ||
824 | mntput(path->mnt); | ||
825 | path->mnt = mnt; | 828 | path->mnt = mnt; |
826 | path->dentry = dget(mnt->mnt_root); | 829 | path->dentry = dget(mnt->mnt_root); |
827 | *need_mntput = true; | ||
828 | return 0; | 830 | return 0; |
829 | default: | 831 | default: |
830 | return err; | 832 | return err; |
@@ -844,9 +846,10 @@ static int follow_automount(struct path *path, unsigned flags, | |||
844 | */ | 846 | */ |
845 | static int follow_managed(struct path *path, unsigned flags) | 847 | static int follow_managed(struct path *path, unsigned flags) |
846 | { | 848 | { |
849 | struct vfsmount *mnt = path->mnt; /* held by caller, must be left alone */ | ||
847 | unsigned managed; | 850 | unsigned managed; |
848 | bool need_mntput = false; | 851 | bool need_mntput = false; |
849 | int ret; | 852 | int ret = 0; |
850 | 853 | ||
851 | /* Given that we're not holding a lock here, we retain the value in a | 854 | /* Given that we're not holding a lock here, we retain the value in a |
852 | * local variable for each dentry as we look at it so that we don't see | 855 | * local variable for each dentry as we look at it so that we don't see |
@@ -861,7 +864,7 @@ static int follow_managed(struct path *path, unsigned flags) | |||
861 | BUG_ON(!path->dentry->d_op->d_manage); | 864 | BUG_ON(!path->dentry->d_op->d_manage); |
862 | ret = path->dentry->d_op->d_manage(path->dentry, false); | 865 | ret = path->dentry->d_op->d_manage(path->dentry, false); |
863 | if (ret < 0) | 866 | if (ret < 0) |
864 | return ret == -EISDIR ? 0 : ret; | 867 | break; |
865 | } | 868 | } |
866 | 869 | ||
867 | /* Transit to a mounted filesystem. */ | 870 | /* Transit to a mounted filesystem. */ |
@@ -887,14 +890,19 @@ static int follow_managed(struct path *path, unsigned flags) | |||
887 | if (managed & DCACHE_NEED_AUTOMOUNT) { | 890 | if (managed & DCACHE_NEED_AUTOMOUNT) { |
888 | ret = follow_automount(path, flags, &need_mntput); | 891 | ret = follow_automount(path, flags, &need_mntput); |
889 | if (ret < 0) | 892 | if (ret < 0) |
890 | return ret == -EISDIR ? 0 : ret; | 893 | break; |
891 | continue; | 894 | continue; |
892 | } | 895 | } |
893 | 896 | ||
894 | /* We didn't change the current path point */ | 897 | /* We didn't change the current path point */ |
895 | break; | 898 | break; |
896 | } | 899 | } |
897 | return 0; | 900 | |
901 | if (need_mntput && path->mnt == mnt) | ||
902 | mntput(path->mnt); | ||
903 | if (ret == -EISDIR) | ||
904 | ret = 0; | ||
905 | return ret; | ||
898 | } | 906 | } |
899 | 907 | ||
900 | int follow_down_one(struct path *path) | 908 | int follow_down_one(struct path *path) |
@@ -2713,8 +2721,10 @@ static long do_unlinkat(int dfd, const char __user *pathname) | |||
2713 | error = PTR_ERR(dentry); | 2721 | error = PTR_ERR(dentry); |
2714 | if (!IS_ERR(dentry)) { | 2722 | if (!IS_ERR(dentry)) { |
2715 | /* Why not before? Because we want correct error value */ | 2723 | /* Why not before? Because we want correct error value */ |
2724 | if (nd.last.name[nd.last.len]) | ||
2725 | goto slashes; | ||
2716 | inode = dentry->d_inode; | 2726 | inode = dentry->d_inode; |
2717 | if (nd.last.name[nd.last.len] || !inode) | 2727 | if (!inode) |
2718 | goto slashes; | 2728 | goto slashes; |
2719 | ihold(inode); | 2729 | ihold(inode); |
2720 | error = mnt_want_write(nd.path.mnt); | 2730 | error = mnt_want_write(nd.path.mnt); |
diff --git a/fs/proc/root.c b/fs/proc/root.c index a9000e9cfee5..d6c3b416529b 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c | |||
@@ -28,11 +28,12 @@ static int proc_test_super(struct super_block *sb, void *data) | |||
28 | 28 | ||
29 | static int proc_set_super(struct super_block *sb, void *data) | 29 | static int proc_set_super(struct super_block *sb, void *data) |
30 | { | 30 | { |
31 | struct pid_namespace *ns; | 31 | int err = set_anon_super(sb, NULL); |
32 | 32 | if (!err) { | |
33 | ns = (struct pid_namespace *)data; | 33 | struct pid_namespace *ns = (struct pid_namespace *)data; |
34 | sb->s_fs_info = get_pid_ns(ns); | 34 | sb->s_fs_info = get_pid_ns(ns); |
35 | return set_anon_super(sb, NULL); | 35 | } |
36 | return err; | ||
36 | } | 37 | } |
37 | 38 | ||
38 | static struct dentry *proc_mount(struct file_system_type *fs_type, | 39 | static struct dentry *proc_mount(struct file_system_type *fs_type, |
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c index 266895783b47..e34f0d99ea4e 100644 --- a/fs/sysfs/mount.c +++ b/fs/sysfs/mount.c | |||
@@ -95,6 +95,14 @@ static int sysfs_set_super(struct super_block *sb, void *data) | |||
95 | return error; | 95 | return error; |
96 | } | 96 | } |
97 | 97 | ||
98 | static void free_sysfs_super_info(struct sysfs_super_info *info) | ||
99 | { | ||
100 | int type; | ||
101 | for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++) | ||
102 | kobj_ns_drop(type, info->ns[type]); | ||
103 | kfree(info); | ||
104 | } | ||
105 | |||
98 | static struct dentry *sysfs_mount(struct file_system_type *fs_type, | 106 | static struct dentry *sysfs_mount(struct file_system_type *fs_type, |
99 | int flags, const char *dev_name, void *data) | 107 | int flags, const char *dev_name, void *data) |
100 | { | 108 | { |
@@ -108,11 +116,11 @@ static struct dentry *sysfs_mount(struct file_system_type *fs_type, | |||
108 | return ERR_PTR(-ENOMEM); | 116 | return ERR_PTR(-ENOMEM); |
109 | 117 | ||
110 | for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++) | 118 | for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++) |
111 | info->ns[type] = kobj_ns_current(type); | 119 | info->ns[type] = kobj_ns_grab_current(type); |
112 | 120 | ||
113 | sb = sget(fs_type, sysfs_test_super, sysfs_set_super, info); | 121 | sb = sget(fs_type, sysfs_test_super, sysfs_set_super, info); |
114 | if (IS_ERR(sb) || sb->s_fs_info != info) | 122 | if (IS_ERR(sb) || sb->s_fs_info != info) |
115 | kfree(info); | 123 | free_sysfs_super_info(info); |
116 | if (IS_ERR(sb)) | 124 | if (IS_ERR(sb)) |
117 | return ERR_CAST(sb); | 125 | return ERR_CAST(sb); |
118 | if (!sb->s_root) { | 126 | if (!sb->s_root) { |
@@ -131,12 +139,11 @@ static struct dentry *sysfs_mount(struct file_system_type *fs_type, | |||
131 | static void sysfs_kill_sb(struct super_block *sb) | 139 | static void sysfs_kill_sb(struct super_block *sb) |
132 | { | 140 | { |
133 | struct sysfs_super_info *info = sysfs_info(sb); | 141 | struct sysfs_super_info *info = sysfs_info(sb); |
134 | |||
135 | /* Remove the superblock from fs_supers/s_instances | 142 | /* Remove the superblock from fs_supers/s_instances |
136 | * so we can't find it, before freeing sysfs_super_info. | 143 | * so we can't find it, before freeing sysfs_super_info. |
137 | */ | 144 | */ |
138 | kill_anon_super(sb); | 145 | kill_anon_super(sb); |
139 | kfree(info); | 146 | free_sysfs_super_info(info); |
140 | } | 147 | } |
141 | 148 | ||
142 | static struct file_system_type sysfs_fs_type = { | 149 | static struct file_system_type sysfs_fs_type = { |
@@ -145,28 +152,6 @@ static struct file_system_type sysfs_fs_type = { | |||
145 | .kill_sb = sysfs_kill_sb, | 152 | .kill_sb = sysfs_kill_sb, |
146 | }; | 153 | }; |
147 | 154 | ||
148 | void sysfs_exit_ns(enum kobj_ns_type type, const void *ns) | ||
149 | { | ||
150 | struct super_block *sb; | ||
151 | |||
152 | mutex_lock(&sysfs_mutex); | ||
153 | spin_lock(&sb_lock); | ||
154 | list_for_each_entry(sb, &sysfs_fs_type.fs_supers, s_instances) { | ||
155 | struct sysfs_super_info *info = sysfs_info(sb); | ||
156 | /* | ||
157 | * If we see a superblock on the fs_supers/s_instances | ||
158 | * list the unmount has not completed and sb->s_fs_info | ||
159 | * points to a valid struct sysfs_super_info. | ||
160 | */ | ||
161 | /* Ignore superblocks with the wrong ns */ | ||
162 | if (info->ns[type] != ns) | ||
163 | continue; | ||
164 | info->ns[type] = NULL; | ||
165 | } | ||
166 | spin_unlock(&sb_lock); | ||
167 | mutex_unlock(&sysfs_mutex); | ||
168 | } | ||
169 | |||
170 | int __init sysfs_init(void) | 155 | int __init sysfs_init(void) |
171 | { | 156 | { |
172 | int err = -ENOMEM; | 157 | int err = -ENOMEM; |
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index 3d28af31d863..2ed2404f3113 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h | |||
@@ -136,7 +136,7 @@ struct sysfs_addrm_cxt { | |||
136 | * instance). | 136 | * instance). |
137 | */ | 137 | */ |
138 | struct sysfs_super_info { | 138 | struct sysfs_super_info { |
139 | const void *ns[KOBJ_NS_TYPES]; | 139 | void *ns[KOBJ_NS_TYPES]; |
140 | }; | 140 | }; |
141 | #define sysfs_info(SB) ((struct sysfs_super_info *)(SB->s_fs_info)) | 141 | #define sysfs_info(SB) ((struct sysfs_super_info *)(SB->s_fs_info)) |
142 | extern struct sysfs_dirent sysfs_root; | 142 | extern struct sysfs_dirent sysfs_root; |
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index b5aeb5a8ebed..8c892c2d5300 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -1848,7 +1848,6 @@ static void ubifs_put_super(struct super_block *sb) | |||
1848 | bdi_destroy(&c->bdi); | 1848 | bdi_destroy(&c->bdi); |
1849 | ubi_close_volume(c->ubi); | 1849 | ubi_close_volume(c->ubi); |
1850 | mutex_unlock(&c->umount_mutex); | 1850 | mutex_unlock(&c->umount_mutex); |
1851 | kfree(c); | ||
1852 | } | 1851 | } |
1853 | 1852 | ||
1854 | static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data) | 1853 | static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data) |
@@ -1971,61 +1970,65 @@ static struct ubi_volume_desc *open_ubi(const char *name, int mode) | |||
1971 | return ERR_PTR(-EINVAL); | 1970 | return ERR_PTR(-EINVAL); |
1972 | } | 1971 | } |
1973 | 1972 | ||
1974 | static int ubifs_fill_super(struct super_block *sb, void *data, int silent) | 1973 | static struct ubifs_info *alloc_ubifs_info(struct ubi_volume_desc *ubi) |
1975 | { | 1974 | { |
1976 | struct ubi_volume_desc *ubi = sb->s_fs_info; | ||
1977 | struct ubifs_info *c; | 1975 | struct ubifs_info *c; |
1978 | struct inode *root; | ||
1979 | int err; | ||
1980 | 1976 | ||
1981 | c = kzalloc(sizeof(struct ubifs_info), GFP_KERNEL); | 1977 | c = kzalloc(sizeof(struct ubifs_info), GFP_KERNEL); |
1982 | if (!c) | 1978 | if (c) { |
1983 | return -ENOMEM; | 1979 | spin_lock_init(&c->cnt_lock); |
1980 | spin_lock_init(&c->cs_lock); | ||
1981 | spin_lock_init(&c->buds_lock); | ||
1982 | spin_lock_init(&c->space_lock); | ||
1983 | spin_lock_init(&c->orphan_lock); | ||
1984 | init_rwsem(&c->commit_sem); | ||
1985 | mutex_init(&c->lp_mutex); | ||
1986 | mutex_init(&c->tnc_mutex); | ||
1987 | mutex_init(&c->log_mutex); | ||
1988 | mutex_init(&c->mst_mutex); | ||
1989 | mutex_init(&c->umount_mutex); | ||
1990 | mutex_init(&c->bu_mutex); | ||
1991 | mutex_init(&c->write_reserve_mutex); | ||
1992 | init_waitqueue_head(&c->cmt_wq); | ||
1993 | c->buds = RB_ROOT; | ||
1994 | c->old_idx = RB_ROOT; | ||
1995 | c->size_tree = RB_ROOT; | ||
1996 | c->orph_tree = RB_ROOT; | ||
1997 | INIT_LIST_HEAD(&c->infos_list); | ||
1998 | INIT_LIST_HEAD(&c->idx_gc); | ||
1999 | INIT_LIST_HEAD(&c->replay_list); | ||
2000 | INIT_LIST_HEAD(&c->replay_buds); | ||
2001 | INIT_LIST_HEAD(&c->uncat_list); | ||
2002 | INIT_LIST_HEAD(&c->empty_list); | ||
2003 | INIT_LIST_HEAD(&c->freeable_list); | ||
2004 | INIT_LIST_HEAD(&c->frdi_idx_list); | ||
2005 | INIT_LIST_HEAD(&c->unclean_leb_list); | ||
2006 | INIT_LIST_HEAD(&c->old_buds); | ||
2007 | INIT_LIST_HEAD(&c->orph_list); | ||
2008 | INIT_LIST_HEAD(&c->orph_new); | ||
2009 | c->no_chk_data_crc = 1; | ||
2010 | |||
2011 | c->highest_inum = UBIFS_FIRST_INO; | ||
2012 | c->lhead_lnum = c->ltail_lnum = UBIFS_LOG_LNUM; | ||
2013 | |||
2014 | ubi_get_volume_info(ubi, &c->vi); | ||
2015 | ubi_get_device_info(c->vi.ubi_num, &c->di); | ||
2016 | } | ||
2017 | return c; | ||
2018 | } | ||
1984 | 2019 | ||
1985 | spin_lock_init(&c->cnt_lock); | 2020 | static int ubifs_fill_super(struct super_block *sb, void *data, int silent) |
1986 | spin_lock_init(&c->cs_lock); | 2021 | { |
1987 | spin_lock_init(&c->buds_lock); | 2022 | struct ubifs_info *c = sb->s_fs_info; |
1988 | spin_lock_init(&c->space_lock); | 2023 | struct inode *root; |
1989 | spin_lock_init(&c->orphan_lock); | 2024 | int err; |
1990 | init_rwsem(&c->commit_sem); | ||
1991 | mutex_init(&c->lp_mutex); | ||
1992 | mutex_init(&c->tnc_mutex); | ||
1993 | mutex_init(&c->log_mutex); | ||
1994 | mutex_init(&c->mst_mutex); | ||
1995 | mutex_init(&c->umount_mutex); | ||
1996 | mutex_init(&c->bu_mutex); | ||
1997 | mutex_init(&c->write_reserve_mutex); | ||
1998 | init_waitqueue_head(&c->cmt_wq); | ||
1999 | c->buds = RB_ROOT; | ||
2000 | c->old_idx = RB_ROOT; | ||
2001 | c->size_tree = RB_ROOT; | ||
2002 | c->orph_tree = RB_ROOT; | ||
2003 | INIT_LIST_HEAD(&c->infos_list); | ||
2004 | INIT_LIST_HEAD(&c->idx_gc); | ||
2005 | INIT_LIST_HEAD(&c->replay_list); | ||
2006 | INIT_LIST_HEAD(&c->replay_buds); | ||
2007 | INIT_LIST_HEAD(&c->uncat_list); | ||
2008 | INIT_LIST_HEAD(&c->empty_list); | ||
2009 | INIT_LIST_HEAD(&c->freeable_list); | ||
2010 | INIT_LIST_HEAD(&c->frdi_idx_list); | ||
2011 | INIT_LIST_HEAD(&c->unclean_leb_list); | ||
2012 | INIT_LIST_HEAD(&c->old_buds); | ||
2013 | INIT_LIST_HEAD(&c->orph_list); | ||
2014 | INIT_LIST_HEAD(&c->orph_new); | ||
2015 | c->no_chk_data_crc = 1; | ||
2016 | 2025 | ||
2017 | c->vfs_sb = sb; | 2026 | c->vfs_sb = sb; |
2018 | c->highest_inum = UBIFS_FIRST_INO; | ||
2019 | c->lhead_lnum = c->ltail_lnum = UBIFS_LOG_LNUM; | ||
2020 | |||
2021 | ubi_get_volume_info(ubi, &c->vi); | ||
2022 | ubi_get_device_info(c->vi.ubi_num, &c->di); | ||
2023 | |||
2024 | /* Re-open the UBI device in read-write mode */ | 2027 | /* Re-open the UBI device in read-write mode */ |
2025 | c->ubi = ubi_open_volume(c->vi.ubi_num, c->vi.vol_id, UBI_READWRITE); | 2028 | c->ubi = ubi_open_volume(c->vi.ubi_num, c->vi.vol_id, UBI_READWRITE); |
2026 | if (IS_ERR(c->ubi)) { | 2029 | if (IS_ERR(c->ubi)) { |
2027 | err = PTR_ERR(c->ubi); | 2030 | err = PTR_ERR(c->ubi); |
2028 | goto out_free; | 2031 | goto out; |
2029 | } | 2032 | } |
2030 | 2033 | ||
2031 | /* | 2034 | /* |
@@ -2091,24 +2094,29 @@ out_bdi: | |||
2091 | bdi_destroy(&c->bdi); | 2094 | bdi_destroy(&c->bdi); |
2092 | out_close: | 2095 | out_close: |
2093 | ubi_close_volume(c->ubi); | 2096 | ubi_close_volume(c->ubi); |
2094 | out_free: | 2097 | out: |
2095 | kfree(c); | ||
2096 | return err; | 2098 | return err; |
2097 | } | 2099 | } |
2098 | 2100 | ||
2099 | static int sb_test(struct super_block *sb, void *data) | 2101 | static int sb_test(struct super_block *sb, void *data) |
2100 | { | 2102 | { |
2101 | dev_t *dev = data; | 2103 | struct ubifs_info *c1 = data; |
2102 | struct ubifs_info *c = sb->s_fs_info; | 2104 | struct ubifs_info *c = sb->s_fs_info; |
2103 | 2105 | ||
2104 | return c->vi.cdev == *dev; | 2106 | return c->vi.cdev == c1->vi.cdev; |
2107 | } | ||
2108 | |||
2109 | static int sb_set(struct super_block *sb, void *data) | ||
2110 | { | ||
2111 | sb->s_fs_info = data; | ||
2112 | return set_anon_super(sb, NULL); | ||
2105 | } | 2113 | } |
2106 | 2114 | ||
2107 | static struct dentry *ubifs_mount(struct file_system_type *fs_type, int flags, | 2115 | static struct dentry *ubifs_mount(struct file_system_type *fs_type, int flags, |
2108 | const char *name, void *data) | 2116 | const char *name, void *data) |
2109 | { | 2117 | { |
2110 | struct ubi_volume_desc *ubi; | 2118 | struct ubi_volume_desc *ubi; |
2111 | struct ubi_volume_info vi; | 2119 | struct ubifs_info *c; |
2112 | struct super_block *sb; | 2120 | struct super_block *sb; |
2113 | int err; | 2121 | int err; |
2114 | 2122 | ||
@@ -2125,19 +2133,24 @@ static struct dentry *ubifs_mount(struct file_system_type *fs_type, int flags, | |||
2125 | name, (int)PTR_ERR(ubi)); | 2133 | name, (int)PTR_ERR(ubi)); |
2126 | return ERR_CAST(ubi); | 2134 | return ERR_CAST(ubi); |
2127 | } | 2135 | } |
2128 | ubi_get_volume_info(ubi, &vi); | ||
2129 | 2136 | ||
2130 | dbg_gen("opened ubi%d_%d", vi.ubi_num, vi.vol_id); | 2137 | c = alloc_ubifs_info(ubi); |
2138 | if (!c) { | ||
2139 | err = -ENOMEM; | ||
2140 | goto out_close; | ||
2141 | } | ||
2142 | |||
2143 | dbg_gen("opened ubi%d_%d", c->vi.ubi_num, c->vi.vol_id); | ||
2131 | 2144 | ||
2132 | sb = sget(fs_type, &sb_test, &set_anon_super, &vi.cdev); | 2145 | sb = sget(fs_type, sb_test, sb_set, c); |
2133 | if (IS_ERR(sb)) { | 2146 | if (IS_ERR(sb)) { |
2134 | err = PTR_ERR(sb); | 2147 | err = PTR_ERR(sb); |
2135 | goto out_close; | 2148 | kfree(c); |
2136 | } | 2149 | } |
2137 | 2150 | ||
2138 | if (sb->s_root) { | 2151 | if (sb->s_root) { |
2139 | struct ubifs_info *c1 = sb->s_fs_info; | 2152 | struct ubifs_info *c1 = sb->s_fs_info; |
2140 | 2153 | kfree(c); | |
2141 | /* A new mount point for already mounted UBIFS */ | 2154 | /* A new mount point for already mounted UBIFS */ |
2142 | dbg_gen("this ubi volume is already mounted"); | 2155 | dbg_gen("this ubi volume is already mounted"); |
2143 | if (!!(flags & MS_RDONLY) != c1->ro_mount) { | 2156 | if (!!(flags & MS_RDONLY) != c1->ro_mount) { |
@@ -2146,11 +2159,6 @@ static struct dentry *ubifs_mount(struct file_system_type *fs_type, int flags, | |||
2146 | } | 2159 | } |
2147 | } else { | 2160 | } else { |
2148 | sb->s_flags = flags; | 2161 | sb->s_flags = flags; |
2149 | /* | ||
2150 | * Pass 'ubi' to 'fill_super()' in sb->s_fs_info where it is | ||
2151 | * replaced by 'c'. | ||
2152 | */ | ||
2153 | sb->s_fs_info = ubi; | ||
2154 | err = ubifs_fill_super(sb, data, flags & MS_SILENT ? 1 : 0); | 2162 | err = ubifs_fill_super(sb, data, flags & MS_SILENT ? 1 : 0); |
2155 | if (err) | 2163 | if (err) |
2156 | goto out_deact; | 2164 | goto out_deact; |
@@ -2170,11 +2178,18 @@ out_close: | |||
2170 | return ERR_PTR(err); | 2178 | return ERR_PTR(err); |
2171 | } | 2179 | } |
2172 | 2180 | ||
2181 | static void kill_ubifs_super(struct super_block *s) | ||
2182 | { | ||
2183 | struct ubifs_info *c = s->s_fs_info; | ||
2184 | kill_anon_super(s); | ||
2185 | kfree(c); | ||
2186 | } | ||
2187 | |||
2173 | static struct file_system_type ubifs_fs_type = { | 2188 | static struct file_system_type ubifs_fs_type = { |
2174 | .name = "ubifs", | 2189 | .name = "ubifs", |
2175 | .owner = THIS_MODULE, | 2190 | .owner = THIS_MODULE, |
2176 | .mount = ubifs_mount, | 2191 | .mount = ubifs_mount, |
2177 | .kill_sb = kill_anon_super, | 2192 | .kill_sb = kill_ubifs_super, |
2178 | }; | 2193 | }; |
2179 | 2194 | ||
2180 | /* | 2195 | /* |