permit fs->get_sb() to return alternative root
Subsystems (31)
David Howells
maintainerPATCH 1/1 permit fs->get_sb() to return alternative root
Hi Al, Linux,
Here's a patch to add an extra argument to the get_sb() method of struct file_system_type that allows a filesystem to suggest an alternative dentry to be attached to the vfsmount structure. If no such suggestion is made, sb->s_root is selected as usual.
The reason I want this is so that the NFS fs can be improved such that two mounts made from the same server will be able to use the same superblock, the same inodes and the same dentries (as I've been discussing with Trond), this eliminating aliasing at the client end.
This deals with the case of doing, for instance:
mount file:/export/home0/dhowells /home/dhowells mount file:/export/home0/dwmw2 /home/dwmw2
And then finding you've got files hard-linked across the two.
In effect, you get a sort of bind mount.
It also means that local on-disc caching becomes feasible with cachefs.
David
include/linux/fs.h +1 -1
@@ -1086,7 +1086,7 @@const char *name;int fs_flags;struct super_block *(*get_sb) (struct file_system_type *,int , -const char *,void *); +const char *,void *,struct dentry **);void (*kill_sb) (struct super_block *);struct module *owner;struct file_system_type * next;
fs/super.c +7 -3
@@ -738,6 +738,7 @@struct file_system_type *type =get_fs_type (fstype);struct super_block *sb =ERR_PTR (-ENOMEM );struct vfsmount *mnt; +struct dentry *root;int error;char *secdata =NULL ;
@@ -762,15 +763,18 @@ } } - sb = type->get_sb (type, flags, name, data); + root =NULL ; + sb = type->get_sb (type, flags, name, data, &root);if (IS_ERR (sb)) goto out_free_secdata; +if (!root) + root = sb->s_root; error =security_sb_kern_mount (sb, secdata);if (error) goto out_sb; mnt->mnt_sb = sb; - mnt->mnt_root =dget (sb->s_root); - mnt->mnt_mountpoint = sb->s_root; + mnt->mnt_root =dget (root); + mnt->mnt_mountpoint = mnt->mnt_root; mnt->mnt_parent = mnt;up_write (&sb->s_umount);put_filesystem (type);
arch/ia64/kernel/perfmon.c +2 -1
@@ -592,7 +592,8 @@static struct super_block * -pfmfs_get_sb (struct file_system_type *fs_type,int flags,const char *dev_name,void *data) +pfmfs_get_sb (struct file_system_type *fs_type,int flags,const char *dev_name,void *data, +struct dentry **_root) {return get_sb_pseudo (fs_type,"pfm:" ,NULL ,PFMFS_MAGIC ); }
arch/ia64/sn/io/hwgfs/ramfs.c +1 -1
@@ -165,7 +165,7 @@ }static struct super_block *hwgfs_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_single (fs_type, flags, data, hwgfs_fill_super); }
drivers/isdn/capi/capifs.c +1 -1
@@ -118,7 +118,7 @@ }static struct super_block *capifs_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_single (fs_type, flags, data, capifs_fill_super); }
drivers/misc/ibmasm/ibmasmfs.c +2 -1
@@ -103,7 +103,8 @@static struct super_block *ibmasmfs_get_super (struct file_system_type *fst, -int flags,const char *name,void *data) +int flags,const char *name,void *data, +struct dentry **_root) {return get_sb_single (fst, flags, data, ibmasmfs_fill_super); }
drivers/oprofile/oprofilefs.c +1 -1
@@ -300,7 +300,7 @@static struct super_block *oprofilefs_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_single (fs_type, flags, data, oprofilefs_fill_super); }
drivers/usb/core/inode.c +1 -1
@@ -497,7 +497,7 @@static struct file_system_type usbdevice_fs_type;static struct super_block *usb_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_single (fs_type, flags, data, usbfs_fill_super); }
drivers/usb/gadget/inode.c +1 -1
@@ -1842,7 +1842,7 @@/* "mount -t gadgetfs path /dev/gadget" ends up here */ static struct super_block *gadgetfs_get_sb (struct file_system_type *t,int flags, -const char *path,void *opts) +const char *path,void *opts,struct dentry **_root) {return get_sb_single (t, flags, opts, gadgetfs_fill_super); }
fs/adfs/super.c +1 -1
@@ -470,7 +470,7 @@ }static struct super_block *adfs_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_bdev (fs_type, flags, dev_name, data, adfs_fill_super); }
fs/affs/super.c +1 -1
@@ -546,7 +546,7 @@ }static struct super_block *affs_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_bdev (fs_type, flags, dev_name, data, affs_fill_super); }
fs/afs/super.c +3 -2
@@ -40,7 +40,7 @@static struct super_block *afs_get_sb (struct file_system_type *fs_type,int flags,const char *dev_name, -void *data); +void *data,struct dentry **_root);static struct inode *afs_alloc_inode (struct super_block *sb);
@@ -299,7 +299,8 @@static struct super_block *afs_get_sb (struct file_system_type *fs_type,int flags,const char *dev_name, -void *options) +void *options, +struct dentry **_root) {struct afs_mount_params params;struct super_block *sb;
fs/autofs/init.c +1 -1
@@ -15,7 +15,7 @@#include "autofs_i.h" static struct super_block *autofs_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_nodev (fs_type, flags, data, autofs_fill_super); }
fs/autofs4/init.c +1 -1
@@ -15,7 +15,7 @@#include "autofs_i.h" static struct super_block *autofs_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_nodev (fs_type, flags, data, autofs4_fill_super); }
fs/befs/linuxvfs.c +1 -1
@@ -928,7 +928,7 @@static struct super_block *befs_get_sb (struct file_system_type *fs_type,int flags,const char *dev_name, -void *data) +void *data,struct dentry **_root) {return get_sb_bdev (fs_type, flags, dev_name, data, befs_fill_super); }
fs/bfs/inode.c +1 -1
@@ -381,7 +381,7 @@ }static struct super_block *bfs_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_bdev (fs_type, flags, dev_name, data, bfs_fill_super); }
fs/binfmt_misc.c +1 -1
@@ -622,7 +622,7 @@ }static struct super_block *bm_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_single (fs_type, flags, data, bm_fill_super); }
fs/cifs/cifsfs.c +1 -1
@@ -398,7 +398,7 @@static struct super_block *cifs_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) + int flags, const char *dev_name, void *data, , struct dentry **_root) {int rc;struct super_block *sb =sget (fs_type,NULL , set_anon_super,NULL );
fs/coda/inode.c +1 -1
@@ -306,7 +306,7 @@/* init_coda: used by filesystems.c to register coda */ static struct super_block *coda_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_nodev (fs_type, flags, data, coda_fill_super); }
fs/cramfs/inode.c +1 -1
@@ -494,7 +494,7 @@ };static struct super_block *cramfs_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_bdev (fs_type, flags, dev_name, data, cramfs_fill_super); }
fs/devfs/base.c +1 -1
@@ -2566,7 +2566,7 @@static struct super_block *devfs_get_sb (struct file_system_type *fs_type,int flags,const char *dev_name, -void *data) +void *data,struct dentry **_root) {return get_sb_single (fs_type, flags, data, devfs_fill_super); }
fs/devpts/inode.c +1 -1
@@ -109,7 +109,7 @@ }static struct super_block *devpts_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_single (fs_type, flags, data, devpts_fill_super); }
fs/efs/super.c +1 -1
@@ -16,7 +16,7 @@#include <linux/vfs.h> static struct super_block *efs_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_bdev (fs_type, flags, dev_name, data, efs_fill_super); }
fs/eventpoll.c +2 -2
@@ -326,7 +326,7 @@static struct inode *ep_eventpoll_inode (void );static struct super_block *eventpollfs_get_sb (struct file_system_type *fs_type,int flags,const char *dev_name, -void *data); +void *data,struct dentry **_root);/* * This semaphore is used to serialize ep_free() and eventpoll_release_file().
@@ -1679,7 +1679,7 @@static struct super_block *eventpollfs_get_sb (struct file_system_type *fs_type,int flags, -const char *dev_name,void *data) +const char *dev_name,void *data,struct dentry **_root) {return get_sb_pseudo (fs_type,"eventpoll:" ,NULL ,EVENTPOLLFS_MAGIC ); }
fs/ext2/super.c +1 -1
@@ -1008,7 +1008,7 @@ }static struct super_block *ext2_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_bdev (fs_type, flags, dev_name, data, ext2_fill_super); }
fs/ext3/super.c +1 -1
@@ -2280,7 +2280,7 @@#endif static struct super_block *ext3_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_bdev (fs_type, flags, dev_name, data, ext3_fill_super); }
fs/freevxfs/vxfs_super.c +1 -1
@@ -243,7 +243,7 @@* The usual module blurb. */ static struct super_block *vxfs_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_bdev (fs_type, flags, dev_name, data, vxfs_fill_super); }
fs/hfs/super.c +2 -1
@@ -316,7 +316,8 @@ }static struct super_block *hfs_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data, +struct dentry **_root) {return get_sb_bdev (fs_type, flags, dev_name, data, hfs_fill_super); }
fs/hfsplus/super.c +2 -1
@@ -441,7 +441,8 @@#define HFSPLUS_INODE_SIZE sizeof(struct hfsplus_inode_info)static struct super_block *hfsplus_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data, +struct dentry **_root) {return get_sb_bdev (fs_type, flags, dev_name, data, hfsplus_fill_super); }
fs/hpfs/super.c +1 -1
@@ -661,7 +661,7 @@ }static struct super_block *hpfs_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_bdev (fs_type, flags, dev_name, data, hpfs_fill_super); }
fs/hugetlbfs/inode.c +1 -1
@@ -670,7 +670,7 @@ }static struct super_block *hugetlbfs_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_nodev (fs_type, flags, data, hugetlbfs_fill_super); }
fs/intermezzo/super.c +1 -1
@@ -188,7 +188,7 @@mount options to cache FS */ struct super_block *presto_get_sb (struct file_system_type *izo_type,int flags, -const char *devname,void *data) +const char *devname,void *data,struct dentry **_root) {struct file_system_type *fstype;struct presto_cache *cache =NULL ;
fs/isofs/inode.c +1 -1
@@ -1419,7 +1419,7 @@#endif static struct super_block *isofs_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_bdev (fs_type, flags, dev_name, data, isofs_fill_super); }
fs/jffs/inode-v23.c +1 -1
@@ -1788,7 +1788,7 @@ };static struct super_block *jffs_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_bdev (fs_type, flags, dev_name, data, jffs_fill_super); }
fs/jffs2/super.c +1 -1
@@ -167,7 +167,7 @@static struct super_block *jffs2_get_sb (struct file_system_type *fs_type,int flags,const char *dev_name, -void *data) +void *data,struct dentry **_root) {int err;struct nameidata nd;
fs/jfs/super.c +1 -1
@@ -494,7 +494,7 @@ }static struct super_block *jfs_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_bdev (fs_type, flags, dev_name, data, jfs_fill_super); }
fs/minix/inode.c +1 -1
@@ -556,7 +556,7 @@ }static struct super_block *minix_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_bdev (fs_type, flags, dev_name, data, minix_fill_super); }
fs/msdos/namei.c +1 -1
@@ -596,7 +596,7 @@ }static struct super_block *msdos_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_bdev (fs_type, flags, dev_name, data, msdos_fill_super); }
fs/ncpfs/inode.c +1 -1
@@ -963,7 +963,7 @@#endif static struct super_block *ncp_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_nodev (fs_type, flags, data, ncp_fill_super); }
fs/nfs/inode.c +2 -2
@@ -1305,7 +1305,7 @@ }static struct super_block *nfs_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *raw_data) +int flags,const char *dev_name,void *raw_data,struct dentry **_root) {int error;struct nfs_server *server;
@@ -1623,7 +1623,7 @@ }static struct super_block *nfs4_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *raw_data) +int flags,const char *dev_name,void *raw_data,struct dentry **_root) {int error;struct nfs_server *server;
fs/nfsd/nfsctl.c +1 -1
@@ -417,7 +417,7 @@ }static struct super_block *nfsd_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_single (fs_type, flags, data, nfsd_fill_super); }
fs/ntfs/super.c +1 -1
@@ -1999,7 +1999,7 @@DECLARE_MUTEX (ntfs_lock);static struct super_block *ntfs_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_bdev (fs_type, flags, dev_name, data, ntfs_fill_super); }
fs/openpromfs/inode.c +1 -1
@@ -1054,7 +1054,7 @@ }static struct super_block *openprom_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_single (fs_type, flags, data, openprom_fill_super); }
fs/pipe.c +1 -1
@@ -696,7 +696,7 @@*/ static struct super_block *pipefs_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_pseudo (fs_type,"pipe:" ,NULL ,PIPEFS_MAGIC ); }
fs/proc/root.c +1 -1
@@ -25,7 +25,7 @@#endif static struct super_block *proc_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_single (fs_type, flags, data, proc_fill_super); }
fs/qnx4/inode.c +1 -1
@@ -559,7 +559,7 @@ }static struct super_block *qnx4_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_bdev (fs_type, flags, dev_name, data, qnx4_fill_super); }
fs/ramfs/inode.c +2 -2
@@ -199,13 +199,13 @@ }static struct super_block *ramfs_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_nodev (fs_type, flags, data, ramfs_fill_super); }static struct super_block *rootfs_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_nodev (fs_type, flags|MS_NOUSER , data, ramfs_fill_super); }
fs/reiserfs/super.c +1 -1
@@ -1509,7 +1509,7 @@static struct super_block *get_super_block (struct file_system_type *fs_type,int flags, -const char *dev_name,void *data) +const char *dev_name,void *data,struct dentry **_root) {return get_sb_bdev (fs_type, flags, dev_name, data, reiserfs_fill_super); }
fs/romfs/inode.c +1 -1
@@ -607,7 +607,7 @@ };static struct super_block *romfs_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_bdev (fs_type, flags, dev_name, data, romfs_fill_super); }
fs/smbfs/inode.c +1 -1
@@ -776,7 +776,7 @@#endif static struct super_block *smb_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_nodev (fs_type, flags, data, smb_fill_super); }
fs/sysfs/mount.c +1 -1
@@ -55,7 +55,7 @@ }static struct super_block *sysfs_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_single (fs_type, flags, data, sysfs_fill_super); }
fs/sysv/super.c +2 -2
@@ -499,13 +499,13 @@/* Every kernel module contains stuff like this. */ static struct super_block *sysv_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_bdev (fs_type, flags, dev_name, data, sysv_fill_super); }static struct super_block *v7_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_bdev (fs_type, flags, dev_name, data, v7_fill_super); }
fs/udf/super.c +1 -1
@@ -100,7 +100,7 @@/* UDF filesystem type */ static struct super_block *udf_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_bdev (fs_type, flags, dev_name, data, udf_fill_super); }
fs/ufs/super.c +1 -1
@@ -1209,7 +1209,7 @@ };static struct super_block *ufs_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_bdev (fs_type, flags, dev_name, data, ufs_fill_super); }
fs/vfat/namei.c +1 -1
@@ -1121,7 +1121,7 @@ }static struct super_block *vfat_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_bdev (fs_type, flags, dev_name, data, vfat_fill_super); }
fs/xfs/linux/xfs_super.c +2 -1
@@ -745,7 +745,8 @@struct file_system_type *fs_type, int flags, const char *dev_name, - void *data) + void *data, + struct dentry **_root) { return get_sb_bdev(fs_type, flags, dev_name, data, linvfs_fill_super); }
ipc/mqueue.c +1 -1
@@ -168,7 +168,7 @@static struct super_block *mqueue_get_sb (struct file_system_type *fs_type,int flags,const char *dev_name, -void *data) +void *data,struct dentry **_root) {return get_sb_single (fs_type, flags, data, mqueue_fill_super); }
kernel/futex.c +1 -1
@@ -674,7 +674,7 @@static struct super_block *futexfs_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_pseudo (fs_type,"futex" ,NULL ,0xBAD1DEA ); }
mm/shmem.c +1 -1
@@ -1879,7 +1879,7 @@ };static struct super_block *shmem_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_nodev (fs_type, flags, data, shmem_fill_super); }
net/socket.c +1 -1
@@ -323,7 +323,7 @@ };static struct super_block *sockfs_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_pseudo (fs_type,"socket:" , &sockfs_ops,SOCKFS_MAGIC ); }
net/sunrpc/rpc_pipe.c +1 -1
@@ -793,7 +793,7 @@static struct super_block *rpc_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data,struct dentry **_root) {return get_sb_single (fs_type, flags, data, rpc_fill_super); }
security/selinux/selinuxfs.c +2 -1
@@ -1088,7 +1088,8 @@ }static struct super_block *sel_get_sb (struct file_system_type *fs_type, -int flags,const char *dev_name,void *data) +int flags,const char *dev_name,void *data, +struct dentry **_root) {return get_sb_single (fs_type, flags, data, sel_fill_super); }
På ty , 18/05/2004 klokka 10:14, skreiv David Howells:
Quoted 6 lines
Hi Al, Linux,
Here's a patch to add an extra argument to the
get_sb()method of structfile_system_typethat allows a filesystem to suggest an alternative dentry to be attached to the vfsmount structure. If no such suggestion is made,sb->s_rootis selected as usual.
Cool..
Quoted 9 lines
fs/super.c +2
-1@@ -762,15 +763,18 @@ } } - sb = type->get_sb (type, flags, name, data); + root =NULL ; + sb = type->get_sb (type, flags, name, data, &root);if (IS_ERR (sb)) goto out_free_secdata;
fs/super.c line 777
Quoted 10 lines
fs/super.c +4
-2+if (!root) + root = sb->s_root; error =security_sb_kern_mount (sb, secdata);if (error) goto out_sb; mnt->mnt_sb = sb; - mnt->mnt_root =dget (sb->s_root); - mnt->mnt_mountpoint = sb->s_root; + mnt->mnt_root =dget (root); + mnt->mnt_mountpoint = mnt->mnt_root;
This looks a bit iffy... Shouldn't that be
+ if (!root)
+ root = dget(sb->s_root);
....
+ mnt->mnt_root = root;
Unless the filesystem has taken a reference to the dentry in "root", it just won't be guaranteed to still exist.
Cheers,
Trond
-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
David Howells
maintainerQuoted 7 lines
På ty , 18/05/2004 klokka 13:48, skreiv
[email protected]:Quoted 1 line
Details, please. Preferably with a patch that could be read...
Needs work (and adaptation to NFSv4), but the basic algorithm would go along the lines of the following
Okay... I've worked on your patch somewhat. The attached patch permits superblock sharing:
[root@host135 root]# mount hades:/hades /mnt [root@host135 root]# mount hades:/usr /afs [root@host135 root]# mount hades:/hades /x [root@host135 root]# mount hades:/ /y [root@host135 root]# stat /mnt /afs /x /y /y/hades | grep ^Device Device: eh/14d Inode: 3925361 Links: 46 Device: eh/14d Inode: 327041 Links: 19 Device: eh/14d Inode: 3925361 Links: 46 Device: eh/14d Inode: 2 Links: 33 Device: eh/14d Inode: 3925361 Links: 46
And on an NFS export from a different server:
[root@host135 root]# stat /home/dhowells/Mail | grep ^Device Device: 10h/16d Inode: 3620912 Links: 40
However, df doesn't work:-/
David
fs/dcache.c +18 -0
@@ -1247,6 +1247,23 @@ }/** +* d_materialise_dentry - connect a disconnected dentry into the tree +* @dentry: dentry to replace +* @anon: dentry to place into the tree +* +* Prepare an anonymous dentry for life in the superblock's dentry tree as a +* named dentry in place of the dentry to be replaced. +*/ +void d_materialise_dentry (struct dentry *dentry,struct dentry *anon) +{ +switch_names (dentry, anon); +do_switch (dentry->d_name.len, anon->d_name.len); +do_switch (dentry->d_name.hash, anon->d_name.hash); +do_switch (dentry->d_parent, anon->d_parent); + anon->d_flags &= ~DCACHE_DISCONNECTED ; +} + +/** * d_path - return the path of a dentry * @dentry: dentry to report * @vfsmnt: vfsmnt to which the dentry belongs
@@ -1659,6 +1676,7 @@EXPORT_SYMBOL (d_invalidate);EXPORT_SYMBOL (d_lookup);EXPORT_SYMBOL (d_move); +EXPORT_SYMBOL (d_materialise_dentry);EXPORT_SYMBOL (d_path);EXPORT_SYMBOL (d_prune_aliases);EXPORT_SYMBOL (d_rehash);
fs/nfs/dir.c +26 -0
@@ -710,10 +710,12 @@static struct dentry *nfs_lookup (struct inode *dir,struct dentry * dentry,struct nameidata *nd) { +struct dentry *anon;struct inode *inode =NULL ;int error;struct nfs_fh fhandle;struct nfs_fattr fattr; +int found_alias =0 ;dfprintk (VFS ,"NFS: lookup(%s/%s)\n" , dentry->d_parent->d_name.name, dentry->d_name.name);
@@ -746,6 +748,30 @@ inode =nfs_fhget (dentry->d_sb, &fhandle, &fattr);if (!inode) goto out_unlock; + +/* Search for directory aliases arising from multiple mounts from one server */ +if (S_ISDIR (inode->i_mode) && (anon =d_find_alias (inode))) { +spin_lock (&anon->d_lock); +/* Is this a mountpoint that we could splice into our tree? */ +if (IS_ROOT (anon)) { +/* Yes! Convert into an ordinary dentry */ +d_materialise_dentry (dentry, anon); + found_alias =1 ; + }else if (anon->d_name.len == dentry->d_name.len && + !memcmp (anon->d_name.name, dentry->d_name.name, dentry->d_name.len) && + dentry->d_parent == anon->d_parent) + found_alias =1 ; +spin_unlock (&anon->d_lock); +if (found_alias) { +d_drop (anon); +iput (inode); +d_rehash (anon); +return anon; + } +/* Doh! Server appears to be aliasing directories */ +dput (anon); + } + no_entry: error =0 ;d_add (dentry, inode);
fs/nfs/inode.c +121 -51
273 lines not on this page · raw message
include/linux/dcache.h +1 -0
@@ -198,6 +198,7 @@*/ extern void d_instantiate (struct dentry *,struct inode *);extern void d_delete (struct dentry *); +extern void d_materialise_dentry (struct dentry *,struct dentry *);/* allocate/de-allocate */ extern struct dentry *d_alloc (struct dentry *,const struct qstr *);
include/linux/nfs_fs_sb.h +2 -2
@@ -26,14 +26,14 @@unsigned int acdirmax;unsigned int namelen;char * hostname;/* remote hostname */ -struct nfs_fh fh; +// struct nfs_fh fh; struct sockaddr_in addr;#ifdef CONFIG_NFS_V4 /* Our own IP address, as a null-terminated string. * This is used to generate the clientid, and the callback address. */ char ip_addr[16 ]; -char * mnt_path; +// char * mnt_path; struct nfs4_client * nfs4_state;/* all NFSv4 state starts here */ struct list_head nfs4_siblings;/* List of other nfs_server structs * that share the same clientid
David Howells
maintainerContent-Type: text/plain; charset=ISO-8859-1text/plain; charset=US-ASCII
Content-Transfer-Encoding: quoted-printable
Quoted 6 lines
P=E5 ty , 18/05/2004 klokka 13:48, skreiv
[email protected]:Quoted 1 line
Details, please. Preferably with a patch that could be read...
Needs work (and adaptation to NFSv4), but the basic algorithm would go along the lines of the following
Okay... I've worked on your patch somewhat. The attached patch permits superblock sharing:
[root@host135 root]# mount hades:/hades /mnt [root@host135 root]# mount hades:/usr /afs [root@host135 root]# mount hades:/hades /x [root@host135 root]# mount hades:/ /y [root@host135 root]# stat /mnt /afs /x /y /y/hades | grep ^Device Device: eh/14d Inode: 3925361 Links: 46 Device: eh/14d Inode: 327041 Links: 19 Device: eh/14d Inode: 3925361 Links: 46 Device: eh/14d Inode: 2 Links: 33 Device: eh/14d Inode: 3925361 Links: 46
And on an NFS export from a different server:
[root@host135 root]# stat /home/dhowells/Mail | grep ^Device Device: 10h/16d Inode: 3620912 Links: 40
However, df doesn't work on NFS:-/
David
--Multipart_Thu_May_20_12:22:58_2004-1
Content-Type: text/plain; type=patch
Content-Disposition: attachment; filename="nfs-266.diff"
Content-Transfer-Encoding: 7bit
fs/dcache.c +18 -0
@@ -1247,6 +1247,23 @@ }/** +* d_materialise_dentry - connect a disconnected dentry into the tree +* @dentry: dentry to replace +* @anon: dentry to place into the tree +* +* Prepare an anonymous dentry for life in the superblock's dentry tree as a +* named dentry in place of the dentry to be replaced. +*/ +void d_materialise_dentry (struct dentry *dentry,struct dentry *anon) +{ +switch_names (dentry, anon); +do_switch (dentry->d_name.len, anon->d_name.len); +do_switch (dentry->d_name.hash, anon->d_name.hash); +do_switch (dentry->d_parent, anon->d_parent); + anon->d_flags &= ~DCACHE_DISCONNECTED ; +} + +/** * d_path - return the path of a dentry * @dentry: dentry to report * @vfsmnt: vfsmnt to which the dentry belongs
@@ -1659,6 +1676,7 @@EXPORT_SYMBOL (d_invalidate);EXPORT_SYMBOL (d_lookup);EXPORT_SYMBOL (d_move); +EXPORT_SYMBOL (d_materialise_dentry);EXPORT_SYMBOL (d_path);EXPORT_SYMBOL (d_prune_aliases);EXPORT_SYMBOL (d_rehash);
fs/nfs/dir.c +26 -0
@@ -710,10 +710,12 @@static struct dentry *nfs_lookup (struct inode *dir,struct dentry * dentry,struct nameidata *nd) { +struct dentry *anon;struct inode *inode =NULL ;int error;struct nfs_fh fhandle;struct nfs_fattr fattr; +int found_alias =0 ;dfprintk (VFS ,"NFS: lookup(%s/%s)\n" , dentry->d_parent->d_name.name, dentry->d_name.name);
@@ -746,6 +748,30 @@ inode =nfs_fhget (dentry->d_sb, &fhandle, &fattr);if (!inode) goto out_unlock; + +/* Search for directory aliases arising from multiple mounts from one server */ +if (S_ISDIR (inode->i_mode) && (anon =d_find_alias (inode))) { +spin_lock (&anon->d_lock); +/* Is this a mountpoint that we could splice into our tree? */ +if (IS_ROOT (anon)) { +/* Yes! Convert into an ordinary dentry */ +d_materialise_dentry (dentry, anon); + found_alias =1 ; + }else if (anon->d_name.len == dentry->d_name.len && + !memcmp (anon->d_name.name, dentry->d_name.name, dentry->d_name.len) && + dentry->d_parent == anon->d_parent) + found_alias =1 ; +spin_unlock (&anon->d_lock); +if (found_alias) { +d_drop (anon); +iput (inode); +d_rehash (anon); +return anon; + } +/* Doh! Server appears to be aliasing directories */ +dput (anon); + } + no_entry: error =0 ;d_add (dentry, inode);
fs/nfs/inode.c +121 -51
273 lines not on this page · raw message
include/linux/dcache.h +1 -0
@@ -198,6 +198,7 @@*/ extern void d_instantiate (struct dentry *,struct inode *);extern void d_delete (struct dentry *); +extern void d_materialise_dentry (struct dentry *,struct dentry *);/* allocate/de-allocate */ extern struct dentry *d_alloc (struct dentry *,const struct qstr *);
include/linux/nfs_fs_sb.h +2 -2
@@ -26,14 +26,14 @@unsigned int acdirmax;unsigned int namelen;char * hostname;/* remote hostname */ -struct nfs_fh fh; +// struct nfs_fh fh; struct sockaddr_in addr;#ifdef CONFIG_NFS_V4 /* Our own IP address, as a null-terminated string. * This is used to generate the clientid, and the callback address. */ char ip_addr[16 ]; -char * mnt_path; +// char * mnt_path; struct nfs4_client * nfs4_state;/* all NFSv4 state starts here */ struct list_head nfs4_siblings;/* List of other nfs_server structs * that share the same clientid
--Multipart_Thu_May_20_12:22:58_2004-1--