diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-02-20 19:58:03 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-02-20 19:58:03 -0500 |
| commit | aea187c46f7d03ce985e55eb1398d0776a15b928 (patch) | |
| tree | a2f38121839fec4d91e06f2432478c00fba8df1b | |
| parent | d0708b9739f4d184f74ef69fb15d9c26aecb3f10 (diff) | |
| parent | 8f9941aeccc318f243ab3fa55aaa17f4c1cb33f9 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6:
CacheFiles: Fix a race in cachefiles_delete_object() vs rename
vfs: don't call ima_file_check() unconditionally in nfsd_open()
fs: inode - remove 8 bytes of padding on 64bits allowing 1 more objects/slab under slub
Switch proc/self to nd_set_link()
fix LOOKUP_FOLLOW on automount "symlinks"
| -rw-r--r-- | fs/cachefiles/namei.c | 12 | ||||
| -rw-r--r-- | fs/namei.c | 14 | ||||
| -rw-r--r-- | fs/nfsd/vfs.c | 3 | ||||
| -rw-r--r-- | fs/proc/base.c | 24 | ||||
| -rw-r--r-- | include/linux/fs.h | 2 |
5 files changed, 45 insertions, 10 deletions
diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index 14ac4806e291..eeb4986ea7db 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c | |||
| @@ -348,7 +348,17 @@ int cachefiles_delete_object(struct cachefiles_cache *cache, | |||
| 348 | dir = dget_parent(object->dentry); | 348 | dir = dget_parent(object->dentry); |
| 349 | 349 | ||
| 350 | mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); | 350 | mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); |
| 351 | ret = cachefiles_bury_object(cache, dir, object->dentry); | 351 | |
| 352 | /* we need to check that our parent is _still_ our parent - it may have | ||
| 353 | * been renamed */ | ||
| 354 | if (dir == object->dentry->d_parent) { | ||
| 355 | ret = cachefiles_bury_object(cache, dir, object->dentry); | ||
| 356 | } else { | ||
| 357 | /* it got moved, presumably by cachefilesd culling it, so it's | ||
| 358 | * no longer in the key path and we can ignore it */ | ||
| 359 | mutex_unlock(&dir->d_inode->i_mutex); | ||
| 360 | ret = 0; | ||
| 361 | } | ||
| 352 | 362 | ||
| 353 | dput(dir); | 363 | dput(dir); |
| 354 | _leave(" = %d", ret); | 364 | _leave(" = %d", ret); |
diff --git a/fs/namei.c b/fs/namei.c index d62fdc875f22..a4855af776a8 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -823,6 +823,17 @@ fail: | |||
| 823 | } | 823 | } |
| 824 | 824 | ||
| 825 | /* | 825 | /* |
| 826 | * This is a temporary kludge to deal with "automount" symlinks; proper | ||
| 827 | * solution is to trigger them on follow_mount(), so that do_lookup() | ||
| 828 | * would DTRT. To be killed before 2.6.34-final. | ||
| 829 | */ | ||
| 830 | static inline int follow_on_final(struct inode *inode, unsigned lookup_flags) | ||
| 831 | { | ||
| 832 | return inode && unlikely(inode->i_op->follow_link) && | ||
| 833 | ((lookup_flags & LOOKUP_FOLLOW) || S_ISDIR(inode->i_mode)); | ||
| 834 | } | ||
| 835 | |||
| 836 | /* | ||
| 826 | * Name resolution. | 837 | * Name resolution. |
| 827 | * This is the basic name resolution function, turning a pathname into | 838 | * This is the basic name resolution function, turning a pathname into |
| 828 | * the final dentry. We expect 'base' to be positive and a directory. | 839 | * the final dentry. We expect 'base' to be positive and a directory. |
| @@ -942,8 +953,7 @@ last_component: | |||
| 942 | if (err) | 953 | if (err) |
| 943 | break; | 954 | break; |
| 944 | inode = next.dentry->d_inode; | 955 | inode = next.dentry->d_inode; |
| 945 | if ((lookup_flags & LOOKUP_FOLLOW) | 956 | if (follow_on_final(inode, lookup_flags)) { |
| 946 | && inode && inode->i_op->follow_link) { | ||
| 947 | err = do_follow_link(&next, nd); | 957 | err = do_follow_link(&next, nd); |
| 948 | if (err) | 958 | if (err) |
| 949 | goto return_err; | 959 | goto return_err; |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 97d79eff6b7f..8715d194561a 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
| @@ -752,7 +752,8 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, | |||
| 752 | flags, current_cred()); | 752 | flags, current_cred()); |
| 753 | if (IS_ERR(*filp)) | 753 | if (IS_ERR(*filp)) |
| 754 | host_err = PTR_ERR(*filp); | 754 | host_err = PTR_ERR(*filp); |
| 755 | host_err = ima_file_check(*filp, access); | 755 | else |
| 756 | host_err = ima_file_check(*filp, access); | ||
| 756 | out_nfserr: | 757 | out_nfserr: |
| 757 | err = nfserrno(host_err); | 758 | err = nfserrno(host_err); |
| 758 | out: | 759 | out: |
diff --git a/fs/proc/base.c b/fs/proc/base.c index e42bbd843ed1..58324c299165 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
| @@ -2369,16 +2369,30 @@ static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
| 2369 | { | 2369 | { |
| 2370 | struct pid_namespace *ns = dentry->d_sb->s_fs_info; | 2370 | struct pid_namespace *ns = dentry->d_sb->s_fs_info; |
| 2371 | pid_t tgid = task_tgid_nr_ns(current, ns); | 2371 | pid_t tgid = task_tgid_nr_ns(current, ns); |
| 2372 | char tmp[PROC_NUMBUF]; | 2372 | char *name = ERR_PTR(-ENOENT); |
| 2373 | if (!tgid) | 2373 | if (tgid) { |
| 2374 | return ERR_PTR(-ENOENT); | 2374 | name = __getname(); |
| 2375 | sprintf(tmp, "%d", task_tgid_nr_ns(current, ns)); | 2375 | if (!name) |
| 2376 | return ERR_PTR(vfs_follow_link(nd,tmp)); | 2376 | name = ERR_PTR(-ENOMEM); |
| 2377 | else | ||
| 2378 | sprintf(name, "%d", tgid); | ||
| 2379 | } | ||
| 2380 | nd_set_link(nd, name); | ||
| 2381 | return NULL; | ||
| 2382 | } | ||
| 2383 | |||
| 2384 | static void proc_self_put_link(struct dentry *dentry, struct nameidata *nd, | ||
| 2385 | void *cookie) | ||
| 2386 | { | ||
| 2387 | char *s = nd_get_link(nd); | ||
| 2388 | if (!IS_ERR(s)) | ||
| 2389 | __putname(s); | ||
| 2377 | } | 2390 | } |
| 2378 | 2391 | ||
| 2379 | static const struct inode_operations proc_self_inode_operations = { | 2392 | static const struct inode_operations proc_self_inode_operations = { |
| 2380 | .readlink = proc_self_readlink, | 2393 | .readlink = proc_self_readlink, |
| 2381 | .follow_link = proc_self_follow_link, | 2394 | .follow_link = proc_self_follow_link, |
| 2395 | .put_link = proc_self_put_link, | ||
| 2382 | }; | 2396 | }; |
| 2383 | 2397 | ||
| 2384 | /* | 2398 | /* |
diff --git a/include/linux/fs.h b/include/linux/fs.h index b1bcb275b596..ebb1cd5bc241 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
| @@ -729,6 +729,7 @@ struct inode { | |||
| 729 | uid_t i_uid; | 729 | uid_t i_uid; |
| 730 | gid_t i_gid; | 730 | gid_t i_gid; |
| 731 | dev_t i_rdev; | 731 | dev_t i_rdev; |
| 732 | unsigned int i_blkbits; | ||
| 732 | u64 i_version; | 733 | u64 i_version; |
| 733 | loff_t i_size; | 734 | loff_t i_size; |
| 734 | #ifdef __NEED_I_SIZE_ORDERED | 735 | #ifdef __NEED_I_SIZE_ORDERED |
| @@ -738,7 +739,6 @@ struct inode { | |||
| 738 | struct timespec i_mtime; | 739 | struct timespec i_mtime; |
| 739 | struct timespec i_ctime; | 740 | struct timespec i_ctime; |
| 740 | blkcnt_t i_blocks; | 741 | blkcnt_t i_blocks; |
| 741 | unsigned int i_blkbits; | ||
| 742 | unsigned short i_bytes; | 742 | unsigned short i_bytes; |
| 743 | umode_t i_mode; | 743 | umode_t i_mode; |
| 744 | spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */ | 744 | spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */ |
