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"
This commit is contained in:
Linus Torvalds 2010-02-20 16:58:03 -08:00
commit aea187c46f
5 changed files with 45 additions and 10 deletions

View File

@ -348,7 +348,17 @@ int cachefiles_delete_object(struct cachefiles_cache *cache,
dir = dget_parent(object->dentry);
mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
ret = cachefiles_bury_object(cache, dir, object->dentry);
/* we need to check that our parent is _still_ our parent - it may have
* been renamed */
if (dir == object->dentry->d_parent) {
ret = cachefiles_bury_object(cache, dir, object->dentry);
} else {
/* it got moved, presumably by cachefilesd culling it, so it's
* no longer in the key path and we can ignore it */
mutex_unlock(&dir->d_inode->i_mutex);
ret = 0;
}
dput(dir);
_leave(" = %d", ret);

View File

@ -822,6 +822,17 @@ fail:
return PTR_ERR(dentry);
}
/*
* This is a temporary kludge to deal with "automount" symlinks; proper
* solution is to trigger them on follow_mount(), so that do_lookup()
* would DTRT. To be killed before 2.6.34-final.
*/
static inline int follow_on_final(struct inode *inode, unsigned lookup_flags)
{
return inode && unlikely(inode->i_op->follow_link) &&
((lookup_flags & LOOKUP_FOLLOW) || S_ISDIR(inode->i_mode));
}
/*
* Name resolution.
* This is the basic name resolution function, turning a pathname into
@ -942,8 +953,7 @@ last_component:
if (err)
break;
inode = next.dentry->d_inode;
if ((lookup_flags & LOOKUP_FOLLOW)
&& inode && inode->i_op->follow_link) {
if (follow_on_final(inode, lookup_flags)) {
err = do_follow_link(&next, nd);
if (err)
goto return_err;

View File

@ -752,7 +752,8 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
flags, current_cred());
if (IS_ERR(*filp))
host_err = PTR_ERR(*filp);
host_err = ima_file_check(*filp, access);
else
host_err = ima_file_check(*filp, access);
out_nfserr:
err = nfserrno(host_err);
out:

View File

@ -2369,16 +2369,30 @@ static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
{
struct pid_namespace *ns = dentry->d_sb->s_fs_info;
pid_t tgid = task_tgid_nr_ns(current, ns);
char tmp[PROC_NUMBUF];
if (!tgid)
return ERR_PTR(-ENOENT);
sprintf(tmp, "%d", task_tgid_nr_ns(current, ns));
return ERR_PTR(vfs_follow_link(nd,tmp));
char *name = ERR_PTR(-ENOENT);
if (tgid) {
name = __getname();
if (!name)
name = ERR_PTR(-ENOMEM);
else
sprintf(name, "%d", tgid);
}
nd_set_link(nd, name);
return NULL;
}
static void proc_self_put_link(struct dentry *dentry, struct nameidata *nd,
void *cookie)
{
char *s = nd_get_link(nd);
if (!IS_ERR(s))
__putname(s);
}
static const struct inode_operations proc_self_inode_operations = {
.readlink = proc_self_readlink,
.follow_link = proc_self_follow_link,
.put_link = proc_self_put_link,
};
/*

View File

@ -729,6 +729,7 @@ struct inode {
uid_t i_uid;
gid_t i_gid;
dev_t i_rdev;
unsigned int i_blkbits;
u64 i_version;
loff_t i_size;
#ifdef __NEED_I_SIZE_ORDERED
@ -738,7 +739,6 @@ struct inode {
struct timespec i_mtime;
struct timespec i_ctime;
blkcnt_t i_blocks;
unsigned int i_blkbits;
unsigned short i_bytes;
umode_t i_mode;
spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */