Messages in this thread | | | From | David Howells <> | Subject | [PATCH] in VFS automounting | Date | Fri, 13 Jun 2003 11:46:02 +0100 |
| |
Hi Al,
I've come up with a way of doing automounting from within the VFS (see patch) for my AFS filesystem. The core kernel changes aren't particularly extensive, but I'd like your opinion of them. I don't see any obvious races, but that's not to say there aren't any.
This patch involves the adding the following features:
(1) A new dentry operation that (a) marks a dentry as being an automount point, and (b) gets called by the VFS to come up with a vfsmount structure which the VFS then stitches into the mount tree fabric at the appropriate place.
(2) A new lookup flag that is used by sys_*stat() to prevent automounting of the path endpoint. This means "ls -l" in an automounter directory doesn't cause a mount storm, but will display all the mountpoints in that directory as subdirectories (either the underlying mountpoint dir or the root dir of the mounted fs if the mountpoint has been triggered already).
(3) do_kern_mount() is now exported.
As an example, I've implemented this operation for mountpoints in my AFS filesystem client:
static struct dentry_operations afs_fs_mntpt_dentry_operations = { .d_revalidate = afs_d_revalidate, .d_delete = afs_d_delete, .d_automount = afs_mntpt_d_automount, };
struct vfsmount *afs_mntpt_d_automount(struct dentry *mntpt) { struct vfsmount *mnt; struct page *page = NULL; size_t size; char *buf, *devname = NULL; int ret;
ret = -EINVAL; size = mntpt->d_inode->i_size; if (size > PAGE_SIZE - 1) goto error;
ret = -ENOMEM; devname = (char *) get_zeroed_page(GFP_KERNEL); if (!devname) goto error;
/* read the contents of the AFS special symlink */ page = read_cache_page(mntpt->d_inode->i_mapping, 0, (filler_t*)mntpt->d_inode->i_mapping->a_ops->readpage, NULL); if (IS_ERR(page)) { ret = PTR_ERR(page); goto error; }
ret = -EIO; wait_on_page_locked(page); if (!PageUptodate(page) || PageError(page)) goto error;
buf = kmap(page); memcpy(devname, buf, size); kunmap(page); page_cache_release(page); page = NULL;
mnt = do_kern_mount("afs", 0, devname, NULL);
free_page((unsigned long)devname); return mnt;
error: if (page) page_cache_release(page); if (devname) free_page((unsigned long)devname); return ERR_PTR(ret); }
As you can see, the inode attached to the underlying mountpoint can be used to determine _what_ should be mounted.
I've also got some ideas on automatic automount expiry in the VFS, but this involves adding the following:
#define MNT_AUTOEXPIRE 8
struct vfsmount { ... time_t expiry; struct namespace *namespace; };
struct namespace { ... struct timer expiry_timer; };
And then mntput() would timestamp the vfsmount start the timer going (if it's not already active) when mnt_count==1, and the timer routine would walk the namespace's list of mounts looking for expired vfsmounts (obviously this would need to be done in process context somehow).
What do you think?
David
[unhandled content-type:application/octet-stream]
| |