CVS commit: [netbsd-7] src/sys/ufs/ufs
Module Name:src Committed By: snj Date: Thu Jul 16 21:40:22 UTC 2015 Modified Files: src/sys/ufs/ufs [netbsd-7]: ufs_inode.c Log Message: Pull up following revision(s) (requested by hannken in ticket #850): sys/ufs/ufs/ufs_inode.c: revisions 1.93-1.95 Release the glock on VOP_GETPAGES failure. Tripped over by nick@'s failing disk, missing unlock in error branch discovered by jmcneill@. -- ufs_inactive: take UFS_WAPBL_BEGIN() before calling chkiq(). Should fix PR kern/49948 (quota panic) -- ufs_inactive: stop overwriting error status and return the last error seen. Should resolve CID 1306276 (UNUSED_VALUE) To generate a diff of this commit: cvs rdiff -u -r1.90.2.1 -r1.90.2.2 src/sys/ufs/ufs/ufs_inode.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/ufs/ufs/ufs_inode.c diff -u src/sys/ufs/ufs/ufs_inode.c:1.90.2.1 src/sys/ufs/ufs/ufs_inode.c:1.90.2.2 --- src/sys/ufs/ufs/ufs_inode.c:1.90.2.1 Wed Jan 28 18:34:11 2015 +++ src/sys/ufs/ufs/ufs_inode.c Thu Jul 16 21:40:22 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: ufs_inode.c,v 1.90.2.1 2015/01/28 18:34:11 martin Exp $ */ +/* $NetBSD: ufs_inode.c,v 1.90.2.2 2015/07/16 21:40:22 snj Exp $ */ /* * Copyright (c) 1991, 1993 @@ -37,7 +37,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: ufs_inode.c,v 1.90.2.1 2015/01/28 18:34:11 martin Exp $); +__KERNEL_RCSID(0, $NetBSD: ufs_inode.c,v 1.90.2.2 2015/07/16 21:40:22 snj Exp $); #if defined(_KERNEL_OPT) #include opt_ffs.h @@ -84,27 +84,33 @@ ufs_inactive(void *v) } */ *ap = v; struct vnode *vp = ap-a_vp; struct inode *ip = VTOI(vp); - struct mount *transmp; + struct mount *mp = vp-v_mount; mode_t mode; - int error = 0; + int allerror = 0, error; + bool wapbl_locked = false; - UFS_WAPBL_JUNLOCK_ASSERT(vp-v_mount); + UFS_WAPBL_JUNLOCK_ASSERT(mp); - transmp = vp-v_mount; - fstrans_start(transmp, FSTRANS_LAZY); + fstrans_start(mp, FSTRANS_LAZY); /* * Ignore inodes related to stale file handles. */ if (ip-i_mode == 0) goto out; - if (ip-i_nlink = 0 (vp-v_mount-mnt_flag MNT_RDONLY) == 0) { + if (ip-i_nlink = 0 (mp-mnt_flag MNT_RDONLY) == 0) { #ifdef UFS_EXTATTR ufs_extattr_vnode_inactive(vp, curlwp); #endif if (ip-i_size != 0) - error = ufs_truncate(vp, 0, NOCRED); + allerror = ufs_truncate(vp, 0, NOCRED); #if defined(QUOTA) || defined(QUOTA2) - (void)chkiq(ip, -1, NOCRED, 0); + error = UFS_WAPBL_BEGIN(mp); + if (error) { + allerror = error; + } else { + wapbl_locked = true; + (void)chkiq(ip, -1, NOCRED, 0); + } #endif DIP_ASSIGN(ip, rdev, 0); mode = ip-i_mode; @@ -118,21 +124,27 @@ ufs_inactive(void *v) } if (ip-i_flag (IN_CHANGE | IN_UPDATE | IN_MODIFIED)) { - error = UFS_WAPBL_BEGIN(vp-v_mount); - if (error) - goto out; + if (! wapbl_locked) { + error = UFS_WAPBL_BEGIN(mp); + if (error) { +allerror = error; +goto out; + } + wapbl_locked = true; + } UFS_UPDATE(vp, NULL, NULL, 0); - UFS_WAPBL_END(vp-v_mount); } out: + if (wapbl_locked) + UFS_WAPBL_END(mp); /* * If we are done with the inode, reclaim it * so that it can be reused immediately. */ *ap-a_recycle = (ip-i_mode == 0); VOP_UNLOCK(vp); - fstrans_done(transmp); - return (error); + fstrans_done(mp); + return (allerror); } /* @@ -229,6 +241,7 @@ ufs_balloc_range(struct vnode *vp, off_t VM_PROT_WRITE, 0, PGO_SYNCIO | PGO_PASTEOF | PGO_NOBLOCKALLOC | PGO_NOTIMESTAMP | PGO_GLOCKHELD); if (error) { + genfs_node_unlock(vp); goto out; }
CVS commit: [netbsd-7] src/sys/ufs/ufs
Module Name:src Committed By: msaitoh Date: Mon Dec 22 03:32:23 UTC 2014 Modified Files: src/sys/ufs/ufs [netbsd-7]: extattr.h Log Message: Pull up following revision(s) (requested by manu in ticket #350): sys/ufs/ufs/extattr.h: revision 1.11 Bump UFS1 extended attribute max name length to 256 For extended attribute name max length, kernel filesystem-independant code use either EXTATTR_MAXNAMELEN (BSD API) or XATTR_NAME_MAX (Linux API), which are both defined as KERNEL_NAME_MAX and fits Linux limit of 255 without training \0. UFS1 code had a lower limit that broke Linux compatibility. We can bump the limit without sacrifying backward compatibility, because: 1) There is no API exposing this limit outside the kernel. Upper kernel layers have a larger limit handle the increase without a hitch 2) Each attribute has its own backing store in the fileystem, the name of the backing store matching the attribute name. A newer kernel can create/read/write backing store for longer attribute names and will have no problem with existing shorter names. To generate a diff of this commit: cvs rdiff -u -r1.10 -r1.10.28.1 src/sys/ufs/ufs/extattr.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/ufs/ufs/extattr.h diff -u src/sys/ufs/ufs/extattr.h:1.10 src/sys/ufs/ufs/extattr.h:1.10.28.1 --- src/sys/ufs/ufs/extattr.h:1.10 Sun Oct 9 21:15:34 2011 +++ src/sys/ufs/ufs/extattr.h Mon Dec 22 03:32:23 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: extattr.h,v 1.10 2011/10/09 21:15:34 chs Exp $ */ +/* $NetBSD: extattr.h,v 1.10.28.1 2014/12/22 03:32:23 msaitoh Exp $ */ /*- * Copyright (c) 1999-2001 Robert N. M. Watson @@ -43,7 +43,7 @@ #define UFS_EXTATTR_FSROOTSUBDIR .attribute #define UFS_EXTATTR_SUBDIR_SYSTEM system #define UFS_EXTATTR_SUBDIR_USER user -#define UFS_EXTATTR_MAXEXTATTRNAME 65 /* including null */ +#define UFS_EXTATTR_MAXEXTATTRNAME 256 /* including null */ #define UFS_EXTATTR_ATTR_FLAG_INUSE 0x0001 /* attr has been set */ #define UFS_EXTATTR_PERM_KERNEL 0x
CVS commit: [netbsd-7] src/sys/ufs/ufs
Module Name:src Committed By: martin Date: Sun Nov 23 13:11:03 UTC 2014 Modified Files: src/sys/ufs/ufs [netbsd-7]: ufs_extattr.c Log Message: Pull up following revision(s) (requested by manu in ticket #254): sys/ufs/ufs/ufs_extattr.c: revision 1.46 Fix uninitialized mutex usage We use extended attribute mount mutex before testing if it had been initialized, and as reported by Christos, this caused panic with LOCKDEBUG. Fix it by testing before using. To generate a diff of this commit: cvs rdiff -u -r1.43.4.2 -r1.43.4.3 src/sys/ufs/ufs/ufs_extattr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/ufs/ufs/ufs_extattr.c diff -u src/sys/ufs/ufs/ufs_extattr.c:1.43.4.2 src/sys/ufs/ufs/ufs_extattr.c:1.43.4.3 --- src/sys/ufs/ufs/ufs_extattr.c:1.43.4.2 Tue Nov 18 18:42:42 2014 +++ src/sys/ufs/ufs/ufs_extattr.c Sun Nov 23 13:11:02 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: ufs_extattr.c,v 1.43.4.2 2014/11/18 18:42:42 snj Exp $ */ +/* $NetBSD: ufs_extattr.c,v 1.43.4.3 2014/11/23 13:11:02 martin Exp $ */ /*- * Copyright (c) 1999-2002 Robert N. M. Watson @@ -48,7 +48,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: ufs_extattr.c,v 1.43.4.2 2014/11/18 18:42:42 snj Exp $); +__KERNEL_RCSID(0, $NetBSD: ufs_extattr.c,v 1.43.4.3 2014/11/23 13:11:02 martin Exp $); #ifdef _KERNEL_OPT #include opt_ffs.h @@ -1103,6 +1103,9 @@ vop_getextattr { struct ufsmount *ump = VFSTOUFS(mp); int error; + if (!(ump-um_extattr.uepm_flags UFS_EXTATTR_UEPM_STARTED)) + return (EOPNOTSUPP); + ufs_extattr_uepm_lock(ump); error = ufs_extattr_get(ap-a_vp, ap-a_attrnamespace, ap-a_name, @@ -1129,9 +1132,6 @@ ufs_extattr_get(struct vnode *vp, int at size_t len, old_len; int error = 0; - if (!(ump-um_extattr.uepm_flags UFS_EXTATTR_UEPM_STARTED)) - return (EOPNOTSUPP); - if (strlen(name) == 0) return (EINVAL); @@ -1221,6 +1221,9 @@ vop_listextattr { struct ufsmount *ump = VFSTOUFS(mp); int error; + if (!(ump-um_extattr.uepm_flags UFS_EXTATTR_UEPM_STARTED)) + return (EOPNOTSUPP); + ufs_extattr_uepm_lock(ump); error = ufs_extattr_list(ap-a_vp, ap-a_attrnamespace, @@ -1247,9 +1250,6 @@ ufs_extattr_list(struct vnode *vp, int a size_t listsize = 0; int error = 0; - if (!(ump-um_extattr.uepm_flags UFS_EXTATTR_UEPM_STARTED)) - return (EOPNOTSUPP); - /* * XXX: We can move this inside the loop and iterate on individual * attributes. @@ -1348,6 +1348,9 @@ vop_deleteextattr { struct ufsmount *ump = VFSTOUFS(mp); int error; + if (!(ump-um_extattr.uepm_flags UFS_EXTATTR_UEPM_STARTED)) + return (EOPNOTSUPP); + ufs_extattr_uepm_lock(ump); error = ufs_extattr_rm(ap-a_vp, ap-a_attrnamespace, ap-a_name, @@ -1377,6 +1380,9 @@ vop_setextattr { struct ufsmount *ump = VFSTOUFS(mp); int error; + if (!(ump-um_extattr.uepm_flags UFS_EXTATTR_UEPM_STARTED)) + return (EOPNOTSUPP); + ufs_extattr_uepm_lock(ump); /* @@ -1415,8 +1421,7 @@ ufs_extattr_set(struct vnode *vp, int at if (vp-v_mount-mnt_flag MNT_RDONLY) return (EROFS); - if (!(ump-um_extattr.uepm_flags UFS_EXTATTR_UEPM_STARTED)) - return (EOPNOTSUPP); + if (!ufs_extattr_valid_attrname(attrnamespace, name)) return (EINVAL); @@ -1535,8 +1540,7 @@ ufs_extattr_rm(struct vnode *vp, int att if (vp-v_mount-mnt_flag MNT_RDONLY) return (EROFS); - if (!(ump-um_extattr.uepm_flags UFS_EXTATTR_UEPM_STARTED)) - return (EOPNOTSUPP); + if (!ufs_extattr_valid_attrname(attrnamespace, name)) return (EINVAL); @@ -1609,12 +1613,10 @@ ufs_extattr_vnode_inactive(struct vnode if (!(ump-um_extattr.uepm_flags UFS_EXTATTR_UEPM_INITIALIZED)) return; - ufs_extattr_uepm_lock(ump); - - if (!(ump-um_extattr.uepm_flags UFS_EXTATTR_UEPM_STARTED)) { - ufs_extattr_uepm_unlock(ump); + if (!(ump-um_extattr.uepm_flags UFS_EXTATTR_UEPM_STARTED)) return; - } + + ufs_extattr_uepm_lock(ump); LIST_FOREACH(uele, ump-um_extattr.uepm_list, uele_entries) ufs_extattr_rm(vp, uele-uele_attrnamespace,
CVS commit: [netbsd-7] src/sys/ufs/ufs
Module Name:src Committed By: snj Date: Tue Nov 18 18:42:42 UTC 2014 Modified Files: src/sys/ufs/ufs [netbsd-7]: ufs_extattr.c Log Message: Pull up following revision(s) (requested by manu in ticket #247): sys/ufs/ufs/ufs_extattr.c: revision 1.45 Fix UFS1 extended attribute backend autocreation deadlock UFS1 extended attribute backend autocration goes through a vn_open() to create the backend file, and this forces us to release the lock on the target node, in case the target is within the parents of the backend file. That created a window within which another thread could acquire a lock on the target vnode and deadlock awaiting for the mount extended attribute lock. We fix the problem by also releasing the mount extended attribute lock when calling vn_open(), but that lets another thread race us for backend creation. We just detect this using O_EXCL for vn_open() and by checking for EEXIST return code. If we are raced, we fail backend creation but this is not a problem since another thread succeeded on it: we just have to use the result. To generate a diff of this commit: cvs rdiff -u -r1.43.4.1 -r1.43.4.2 src/sys/ufs/ufs/ufs_extattr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/ufs/ufs/ufs_extattr.c diff -u src/sys/ufs/ufs/ufs_extattr.c:1.43.4.1 src/sys/ufs/ufs/ufs_extattr.c:1.43.4.2 --- src/sys/ufs/ufs/ufs_extattr.c:1.43.4.1 Tue Nov 18 18:40:06 2014 +++ src/sys/ufs/ufs/ufs_extattr.c Tue Nov 18 18:42:42 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: ufs_extattr.c,v 1.43.4.1 2014/11/18 18:40:06 snj Exp $ */ +/* $NetBSD: ufs_extattr.c,v 1.43.4.2 2014/11/18 18:42:42 snj Exp $ */ /*- * Copyright (c) 1999-2002 Robert N. M. Watson @@ -48,7 +48,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: ufs_extattr.c,v 1.43.4.1 2014/11/18 18:40:06 snj Exp $); +__KERNEL_RCSID(0, $NetBSD: ufs_extattr.c,v 1.43.4.2 2014/11/18 18:42:42 snj Exp $); #ifdef _KERNEL_OPT #include opt_ffs.h @@ -210,9 +210,9 @@ ufs_extattr_valid_attrname(int attrnames /* * Autocreate an attribute storage */ -static struct ufs_extattr_list_entry * +static int ufs_extattr_autocreate_attr(struct vnode *vp, int attrnamespace, -const char *attrname, struct lwp *l) +const char *attrname, struct lwp *l, struct ufs_extattr_list_entry **uelep) { struct mount *mp = vp-v_mount; struct ufsmount *ump = VFSTOUFS(mp); @@ -246,11 +246,21 @@ ufs_extattr_autocreate_attr(struct vnode break; default: PNBUF_PUT(path); - return NULL; + *uelep = NULL; + return EINVAL; break; } /* + * Release extended attribute mount lock, otherwise + * we can deadlock with another thread that would lock + * vp after we unlock it below, and call + * ufs_extattr_uepm_lock(ump), for instance + * in ufs_getextattr(). + */ + ufs_extattr_uepm_unlock(ump); + + /* * XXX unlock/lock should only be done when setting extattr * on backing store or one of its parent directory * including root, but we always do it for now. @@ -261,7 +271,12 @@ ufs_extattr_autocreate_attr(struct vnode pb = pathbuf_create(path); NDINIT(nd, CREATE, LOCKPARENT, pb); - error = vn_open(nd, O_CREAT|O_RDWR, 0600); + /* + * Since we do not hold ufs_extattr_uepm_lock anymore, + * another thread may race with us for backend creation, + * but only one can succeed here thanks to O_EXCL + */ + error = vn_open(nd, O_CREAT|O_EXCL|O_RDWR, 0600); /* * Reacquire the lock on the vnode @@ -269,10 +284,13 @@ ufs_extattr_autocreate_attr(struct vnode KASSERT(VOP_ISLOCKED(vp) == 0); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); + ufs_extattr_uepm_lock(ump); + if (error != 0) { pathbuf_destroy(pb); PNBUF_PUT(path); - return NULL; + *uelep = NULL; + return error; } KASSERT(nd.ni_vp != NULL); @@ -300,7 +318,8 @@ ufs_extattr_autocreate_attr(struct vnode printf(%s: write uef header failed for %s, error = %d\n, __func__, attrname, error); vn_close(backing_vp, FREAD|FWRITE, l-l_cred); - return NULL; + *uelep = NULL; + return error; } /* @@ -313,7 +332,8 @@ ufs_extattr_autocreate_attr(struct vnode printf(%s: enable %s failed, error %d\n, __func__, attrname, error); vn_close(backing_vp, FREAD|FWRITE, l-l_cred); - return NULL; + *uelep = NULL; + return error; } uele = ufs_extattr_find_attr(ump, attrnamespace, attrname); @@ -321,13 +341,15 @@ ufs_extattr_autocreate_attr(struct vnode printf(%s: atttribute %s created but not found!\n, __func__, attrname); vn_close(backing_vp, FREAD|FWRITE, l-l_cred); - return NULL; + *uelep = NULL; + return ESRCH; /* really internal error */ } printf(%s: EA backing store autocreated for %s\n, mp-mnt_stat.f_mntonname, attrname); - return uele; + *uelep = uele; + return 0; } /* @@ -1405,10 +1427,17 @@ ufs_extattr_set(struct vnode *vp, int at attribute = ufs_extattr_find_attr(ump, attrnamespace,