Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 39719
b: refs/heads/master
c: 91828a4
h: refs/heads/master
i:
  39717: 167bfc4
  39715: cea66c8
  39711: ae1990a
v: v3
  • Loading branch information
David M. Grimes authored and Linus Torvalds committed Oct 17, 2006
1 parent bf54472 commit a9cfb4c
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5c496374a72320279ddb86291ef709e090a5d531
refs/heads/master: 91828a405ae454a9503c41a7744f6ff877a80714
81 changes: 81 additions & 0 deletions trunk/mm/shmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -1362,6 +1362,7 @@ shmem_get_inode(struct super_block *sb, int mode, dev_t dev)
inode->i_mapping->a_ops = &shmem_aops;
inode->i_mapping->backing_dev_info = &shmem_backing_dev_info;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
inode->i_generation = get_seconds();
info = SHMEM_I(inode);
memset(info, 0, (char *)inode - (char *)info);
spin_lock_init(&info->lock);
Expand Down Expand Up @@ -1956,6 +1957,85 @@ static struct xattr_handler *shmem_xattr_handlers[] = {
};
#endif

static struct dentry *shmem_get_parent(struct dentry *child)
{
return ERR_PTR(-ESTALE);
}

static int shmem_match(struct inode *ino, void *vfh)
{
__u32 *fh = vfh;
__u64 inum = fh[2];
inum = (inum << 32) | fh[1];
return ino->i_ino == inum && fh[0] == ino->i_generation;
}

static struct dentry *shmem_get_dentry(struct super_block *sb, void *vfh)
{
struct dentry *de = NULL;
struct inode *inode;
__u32 *fh = vfh;
__u64 inum = fh[2];
inum = (inum << 32) | fh[1];

inode = ilookup5(sb, (unsigned long)(inum+fh[0]), shmem_match, vfh);
if (inode) {
de = d_find_alias(inode);
iput(inode);
}

return de? de: ERR_PTR(-ESTALE);
}

static struct dentry *shmem_decode_fh(struct super_block *sb, __u32 *fh,
int len, int type,
int (*acceptable)(void *context, struct dentry *de),
void *context)
{
if (len < 3)
return ERR_PTR(-ESTALE);

return sb->s_export_op->find_exported_dentry(sb, fh, NULL, acceptable,
context);
}

static int shmem_encode_fh(struct dentry *dentry, __u32 *fh, int *len,
int connectable)
{
struct inode *inode = dentry->d_inode;

if (*len < 3)
return 255;

if (hlist_unhashed(&inode->i_hash)) {
/* Unfortunately insert_inode_hash is not idempotent,
* so as we hash inodes here rather than at creation
* time, we need a lock to ensure we only try
* to do it once
*/
static DEFINE_SPINLOCK(lock);
spin_lock(&lock);
if (hlist_unhashed(&inode->i_hash))
__insert_inode_hash(inode,
inode->i_ino + inode->i_generation);
spin_unlock(&lock);
}

fh[0] = inode->i_generation;
fh[1] = inode->i_ino;
fh[2] = ((__u64)inode->i_ino) >> 32;

*len = 3;
return 1;
}

static struct export_operations shmem_export_ops = {
.get_parent = shmem_get_parent,
.get_dentry = shmem_get_dentry,
.encode_fh = shmem_encode_fh,
.decode_fh = shmem_decode_fh,
};

static int shmem_parse_options(char *options, int *mode, uid_t *uid,
gid_t *gid, unsigned long *blocks, unsigned long *inodes,
int *policy, nodemask_t *policy_nodes)
Expand Down Expand Up @@ -2128,6 +2208,7 @@ static int shmem_fill_super(struct super_block *sb,
&inodes, &policy, &policy_nodes))
return -EINVAL;
}
sb->s_export_op = &shmem_export_ops;
#else
sb->s_flags |= MS_NOUSER;
#endif
Expand Down

0 comments on commit a9cfb4c

Please sign in to comment.