X-Git-Url: https://git.camperquake.de/gitweb.cgi?a=blobdiff_plain;f=module%2Fzfs%2Fzpl_inode.c;h=1f6169b755fd1a2dc406926672a2008304389571;hb=b39d3b9f7be925ba9314c336099f31f508e1d940;hp=9b5533755985845b5d6cbf3f7c5204ee2965111a;hpb=cb2d19010d8fbcf6c22585cd8763fad3ba7db724;p=zfs.git diff --git a/module/zfs/zpl_inode.c b/module/zfs/zpl_inode.c index 9b55337..1f6169b 100644 --- a/module/zfs/zpl_inode.c +++ b/module/zfs/zpl_inode.c @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -51,9 +52,9 @@ zpl_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) return d_splice_alias(ip, dentry); } -static void +void zpl_vap_init(vattr_t *vap, struct inode *dir, struct dentry *dentry, - mode_t mode, cred_t *cr) + zpl_umode_t mode, cred_t *cr) { vap->va_mask = ATTR_MODE; vap->va_mode = mode; @@ -70,7 +71,7 @@ zpl_vap_init(vattr_t *vap, struct inode *dir, struct dentry *dentry, } static int -zpl_create(struct inode *dir, struct dentry *dentry, int mode, +zpl_create(struct inode *dir, struct dentry *dentry, zpl_umode_t mode, struct nameidata *nd) { cred_t *cr = CRED(); @@ -92,7 +93,8 @@ zpl_create(struct inode *dir, struct dentry *dentry, int mode, } static int -zpl_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) +zpl_mknod(struct inode *dir, struct dentry *dentry, zpl_umode_t mode, + dev_t rdev) { cred_t *cr = CRED(); struct inode *ip; @@ -135,7 +137,7 @@ zpl_unlink(struct inode *dir, struct dentry *dentry) } static int -zpl_mkdir(struct inode *dir, struct dentry *dentry, int mode) +zpl_mkdir(struct inode *dir, struct dentry *dentry, zpl_umode_t mode) { cred_t *cr = CRED(); vattr_t *vap; @@ -171,8 +173,20 @@ zpl_rmdir(struct inode * dir, struct dentry *dentry) static int zpl_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) { + boolean_t issnap = ITOZSB(dentry->d_inode)->z_issnap; int error; + /* + * Ensure MNT_SHRINKABLE is set on snapshots to ensure they are + * unmounted automatically with the parent file system. This + * is done on the first getattr because it's not easy to get the + * vfsmount structure at mount time. This call path is explicitly + * marked unlikely to avoid any performance impact. FWIW, ext4 + * resorts to a similar trick for sysadmin convenience. + */ + if (unlikely(issnap && !(mnt->mnt_flags & MNT_SHRINKABLE))) + mnt->mnt_flags |= MNT_SHRINKABLE; + error = -zfs_getattr_fast(dentry->d_inode, stat); ASSERT3S(error, <=, 0);