public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: NeilBrown <neilb@suse.de>
To: Andrew Morton <akpm@osdl.org>
Cc: nfs@lists.sourceforge.net, linux-kernel@vger.kernel.org
Subject: [PATCH 001 of 8] knfsd: Add nfs-export support to tmpfs
Date: Fri, 29 Sep 2006 13:08:39 +1000	[thread overview]
Message-ID: <1060929030839.24024@suse.de> (raw)
In-Reply-To: 20060929130518.23919.patches@notabene


We need to encode a decode the 'file' part of a handle.
We simply use the inode number and generation number to
construct the filehandle.
The generation number is the time when the file was created.
As inode numbers cycle through the full 32 bits before being
reused, there is no real chance of the same inum being allocated
to different files in the same second so this is suitably unique.
Using time-of-day rather than e.g. jiffies makes it less likely that
the same filehandle can be created after a reboot.

In order to be able to decode a filehandle we need to be able to
lookup by inum, which means that the inode needs to be added to the
inode hash table (tmpfs doesn't currently hash inodes as there is never
a need to lookup by inum).  To avoid overhead when not exporting,
we only hash an inode when it is first exported.  This requires a lock
to ensure it isn't hashed twice.

This code is separate from the patch posted in June06 from Atal
Shargorodsky which provided the same functionality, but does borrow
slightly from it.


From: "David M. Grimes" <dgrimes@navisite.com>
Cc: Atal Shargorodsky <atal@codefidence.com>
Cc: Gilad Ben-Yossef <gilad@codefidence.com>


Signed-off-by: David M. Grimes <dgrimes@navisite.com>
Signed-off-by: Neil Brown <neilb@suse.de>

### Diffstat output
 ./mm/shmem.c |   67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff .prev/mm/shmem.c ./mm/shmem.c
--- .prev/mm/shmem.c	2006-09-29 11:52:40.000000000 +1000
+++ ./mm/shmem.c	2006-09-29 11:52:44.000000000 +1000
@@ -1362,6 +1362,7 @@ shmem_get_inode(struct super_block *sb, 
 		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);
@@ -1956,6 +1957,71 @@ static struct xattr_handler *shmem_xattr
 };
 #endif
 
+static struct dentry *shmem_get_parent(struct dentry *child)
+{
+	return ERR_PTR(-ESTALE);
+}
+
+static struct dentry *shmem_get_dentry(struct super_block *sb, void *vfh)
+{
+	struct dentry *de = NULL;
+	struct inode *inode;
+	__u32 *fh = vfh;
+
+	inode = ilookup(sb, (unsigned long)fh[0]);
+	if (inode) {
+		if (inode->i_generation == fh[1])
+			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 < 2)
+		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 < 2)
+		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);
+		spin_unlock(&lock);
+	}
+
+	fh[0] = inode->i_ino;
+	fh[1] = inode->i_generation;
+
+	*len = 2;
+	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)
@@ -2128,6 +2194,7 @@ static int shmem_fill_super(struct super
 					&inodes, &policy, &policy_nodes))
 			return -EINVAL;
 	}
+	sb->s_export_op = &shmem_export_ops;
 #else
 	sb->s_flags |= MS_NOUSER;
 #endif

  reply	other threads:[~2006-09-29  3:08 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-09-29  3:08 [PATCH 000 of 8] knfsd: Introduction NeilBrown
2006-09-29  3:08 ` NeilBrown [this message]
2006-09-29  6:29   ` [PATCH 001 of 8] knfsd: Add nfs-export support to tmpfs Andrew Morton
2006-09-29  6:48     ` [NFS] " Neil Brown
2006-09-29 19:41       ` Hugh Dickins
2006-10-03  0:08         ` Neil Brown
2006-09-29  3:08 ` [PATCH 002 of 8] knfsd: lockd: fix refount on nsm NeilBrown
2006-09-29  6:01   ` [NFS] " Olaf Kirch
2006-09-29  3:08 ` [PATCH 003 of 8] knfsd: Fix auto-sizing of nfsd request/reply buffers NeilBrown
2006-09-29  3:08 ` [PATCH 004 of 8] knfsd: Close a race-opportunity in d_splice_alias NeilBrown
2006-09-29  3:09 ` [PATCH 005 of 8] knfsd: nfsd: store export path in export NeilBrown
2006-09-29  3:09 ` [PATCH 006 of 8] knfsd: nfsd4: fslocations data structures NeilBrown
2006-09-29  6:45   ` Andrew Morton
2006-10-02 18:23     ` [NFS] " J. Bruce Fields
2006-10-02 18:24       ` [PATCH 1 of 3] nfsd4: fix fs locations bounds-checking J. Bruce Fields
2006-10-02 18:26       ` [PATCH 2 of 3] nfsd4: fslocs: fix compile in non-CONFIG_NFSD_V4 case J. Bruce Fields
2006-10-02 18:26       ` [PATCH 3 of 3] nfsd4: fslocs: remove spurious NULL check J. Bruce Fields
2006-09-29  3:09 ` [PATCH 007 of 8] knfsd: nfsd4: xdr encoding for fs_locations NeilBrown
2006-09-29  3:09 ` [PATCH 008 of 8] knfsd: nfsd4: actually use all the pieces to implement referrals NeilBrown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1060929030839.24024@suse.de \
    --to=neilb@suse.de \
    --cc=akpm@osdl.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nfs@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox