aboutsummaryrefslogtreecommitdiffstats
path: root/mm/shmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/shmem.c')
-rw-r--r--mm/shmem.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/mm/shmem.c b/mm/shmem.c
index bb8ca7ef7094..b378f66cf2f9 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1362,6 +1362,7 @@ shmem_get_inode(struct super_block *sb, int mode, dev_t dev)
1362 inode->i_mapping->a_ops = &shmem_aops; 1362 inode->i_mapping->a_ops = &shmem_aops;
1363 inode->i_mapping->backing_dev_info = &shmem_backing_dev_info; 1363 inode->i_mapping->backing_dev_info = &shmem_backing_dev_info;
1364 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; 1364 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
1365 inode->i_generation = get_seconds();
1365 info = SHMEM_I(inode); 1366 info = SHMEM_I(inode);
1366 memset(info, 0, (char *)inode - (char *)info); 1367 memset(info, 0, (char *)inode - (char *)info);
1367 spin_lock_init(&info->lock); 1368 spin_lock_init(&info->lock);
@@ -1956,6 +1957,85 @@ static struct xattr_handler *shmem_xattr_handlers[] = {
1956}; 1957};
1957#endif 1958#endif
1958 1959
1960static struct dentry *shmem_get_parent(struct dentry *child)
1961{
1962 return ERR_PTR(-ESTALE);
1963}
1964
1965static int shmem_match(struct inode *ino, void *vfh)
1966{
1967 __u32 *fh = vfh;
1968 __u64 inum = fh[2];
1969 inum = (inum << 32) | fh[1];
1970 return ino->i_ino == inum && fh[0] == ino->i_generation;
1971}
1972
1973static struct dentry *shmem_get_dentry(struct super_block *sb, void *vfh)
1974{
1975 struct dentry *de = NULL;
1976 struct inode *inode;
1977 __u32 *fh = vfh;
1978 __u64 inum = fh[2];
1979 inum = (inum << 32) | fh[1];
1980
1981 inode = ilookup5(sb, (unsigned long)(inum+fh[0]), shmem_match, vfh);
1982 if (inode) {
1983 de = d_find_alias(inode);
1984 iput(inode);
1985 }
1986
1987 return de? de: ERR_PTR(-ESTALE);
1988}
1989
1990static struct dentry *shmem_decode_fh(struct super_block *sb, __u32 *fh,
1991 int len, int type,
1992 int (*acceptable)(void *context, struct dentry *de),
1993 void *context)
1994{
1995 if (len < 3)
1996 return ERR_PTR(-ESTALE);
1997
1998 return sb->s_export_op->find_exported_dentry(sb, fh, NULL, acceptable,
1999 context);
2000}
2001
2002static int shmem_encode_fh(struct dentry *dentry, __u32 *fh, int *len,
2003 int connectable)
2004{
2005 struct inode *inode = dentry->d_inode;
2006
2007 if (*len < 3)
2008 return 255;
2009
2010 if (hlist_unhashed(&inode->i_hash)) {
2011 /* Unfortunately insert_inode_hash is not idempotent,
2012 * so as we hash inodes here rather than at creation
2013 * time, we need a lock to ensure we only try
2014 * to do it once
2015 */
2016 static DEFINE_SPINLOCK(lock);
2017 spin_lock(&lock);
2018 if (hlist_unhashed(&inode->i_hash))
2019 __insert_inode_hash(inode,
2020 inode->i_ino + inode->i_generation);
2021 spin_unlock(&lock);
2022 }
2023
2024 fh[0] = inode->i_generation;
2025 fh[1] = inode->i_ino;
2026 fh[2] = ((__u64)inode->i_ino) >> 32;
2027
2028 *len = 3;
2029 return 1;
2030}
2031
2032static struct export_operations shmem_export_ops = {
2033 .get_parent = shmem_get_parent,
2034 .get_dentry = shmem_get_dentry,
2035 .encode_fh = shmem_encode_fh,
2036 .decode_fh = shmem_decode_fh,
2037};
2038
1959static int shmem_parse_options(char *options, int *mode, uid_t *uid, 2039static int shmem_parse_options(char *options, int *mode, uid_t *uid,
1960 gid_t *gid, unsigned long *blocks, unsigned long *inodes, 2040 gid_t *gid, unsigned long *blocks, unsigned long *inodes,
1961 int *policy, nodemask_t *policy_nodes) 2041 int *policy, nodemask_t *policy_nodes)
@@ -2128,6 +2208,7 @@ static int shmem_fill_super(struct super_block *sb,
2128 &inodes, &policy, &policy_nodes)) 2208 &inodes, &policy, &policy_nodes))
2129 return -EINVAL; 2209 return -EINVAL;
2130 } 2210 }
2211 sb->s_export_op = &shmem_export_ops;
2131#else 2212#else
2132 sb->s_flags |= MS_NOUSER; 2213 sb->s_flags |= MS_NOUSER;
2133#endif 2214#endif