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 */ |