Page MenuHomeFreeBSD

D49583.id153010.diff
No OneTemporary

D49583.id153010.diff

diff --git a/sys/kern/vfs_cache.c.xattr b/sys/kern/vfs_cache.c
--- a/sys/kern/vfs_cache.c.xattr
+++ b/sys/kern/vfs_cache.c
@@ -4461,7 +4461,7 @@
(NC_NOMAKEENTRY | NC_KEEPPOSENTRY | LOCKLEAF | LOCKPARENT | WANTPARENT | \
FAILIFEXISTS | FOLLOW | EMPTYPATH | LOCKSHARED | ISRESTARTED | WILLBEDIR | \
ISOPEN | NOMACCHECK | AUDITVNODE1 | AUDITVNODE2 | NOCAPCHECK | OPENREAD | \
- OPENWRITE | WANTIOCTLCAPS)
+ OPENWRITE | WANTIOCTLCAPS | OPENNAMED)
#define CACHE_FPL_INTERNAL_CN_FLAGS \
(ISDOTDOT | MAKEENTRY | ISLASTCN)
@@ -4522,6 +4522,10 @@
return (false);
}
if (ndp->ni_startdir != NULL) {
+ cache_fpl_aborted_early(fpl);
+ return (false);
+ }
+ if ((cnp->cn_flags & OPENNAMED) != 0) {
cache_fpl_aborted_early(fpl);
return (false);
}
diff --git a/sys/kern/vfs_default.c.xattr b/sys/kern/vfs_default.c
--- a/sys/kern/vfs_default.c.xattr
+++ b/sys/kern/vfs_default.c
@@ -451,6 +451,7 @@
case _PC_DEALLOC_PRESENT:
case _PC_INF_PRESENT:
case _PC_MAC_PRESENT:
+ case _PC_NAMEDATTR_ENABLED:
*ap->a_retval = 0;
return (0);
default:
diff --git a/sys/kern/vfs_lookup.c.xattr b/sys/kern/vfs_lookup.c
--- a/sys/kern/vfs_lookup.c.xattr
+++ b/sys/kern/vfs_lookup.c
@@ -381,6 +381,7 @@
error = fgetvp_lookup(ndp, dpp);
}
if (error == 0 && (*dpp)->v_type != VDIR &&
+ (cnp->cn_flags & OPENNAMED) == 0 &&
(cnp->cn_pnbuf[0] != '\0' ||
(cnp->cn_flags & EMPTYPATH) == 0))
error = ENOTDIR;
diff --git a/sys/kern/vfs_subr.c.xattr b/sys/kern/vfs_subr.c
--- a/sys/kern/vfs_subr.c.xattr
+++ b/sys/kern/vfs_subr.c
@@ -4772,6 +4772,7 @@
MNT_FLAG(MNT_FORCE);
MNT_FLAG(MNT_SNAPSHOT);
MNT_FLAG(MNT_BYFSID);
+ MNT_FLAG(MNT_NAMEDATTR);
#undef MNT_FLAG
if (mflags != 0) {
if (buf[0] != '\0')
diff --git a/sys/kern/vfs_syscalls.c.xattr b/sys/kern/vfs_syscalls.c
--- a/sys/kern/vfs_syscalls.c.xattr
+++ b/sys/kern/vfs_syscalls.c
@@ -1435,6 +1435,10 @@
vput(nd.ni_dvp);
vrele(vp);
return (EEXIST);
+ } else if ((vn_irflag_read(nd.ni_dvp) & VIRF_NAMEDDIR) != 0) {
+ NDFREE_PNBUF(&nd);
+ vput(nd.ni_dvp);
+ return (EINVAL);
} else {
VATTR_NULL(&vattr);
vattr.va_mode = (mode & ALLPERMS) &
@@ -1543,6 +1547,11 @@
vrele(nd.ni_vp);
return (EEXIST);
}
+ if ((vn_irflag_read(nd.ni_dvp) & VIRF_NAMEDDIR) != 0) {
+ NDFREE_PNBUF(&nd);
+ vput(nd.ni_dvp);
+ return (EINVAL);
+ }
if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
NDFREE_PNBUF(&nd);
vput(nd.ni_dvp);
@@ -1688,6 +1697,10 @@
vrele(vp);
return (EPERM); /* POSIX */
}
+ if ((vn_irflag_read(vp) & (VIRF_NAMEDDIR | VIRF_NAMEDATTR)) != 0) {
+ vrele(vp);
+ return (EINVAL);
+ }
NDINIT_ATRIGHTS(&nd, CREATE,
LOCKPARENT | AUDITVNODE2 | NOCACHE, segflag, path, fd,
&cap_linkat_target_rights);
@@ -1829,6 +1842,10 @@
goto out;
goto restart;
}
+ if ((vn_irflag_read(nd.ni_dvp) & VIRF_NAMEDDIR) != 0) {
+ error = EINVAL;
+ goto out;
+ }
VATTR_NULL(&vattr);
vattr.va_mode = ACCESSPERMS &~ td->td_proc->p_pd->pd_cmask;
#ifdef MAC
@@ -3722,6 +3739,7 @@
struct nameidata fromnd, tond;
uint64_t tondflags;
int error;
+ short irflag;
again:
bwillwrite();
@@ -3774,6 +3792,12 @@
return (error);
goto again;
}
+ irflag = vn_irflag_read(fvp);
+ if (((irflag & VIRF_NAMEDATTR) != 0 && tdvp != fromnd.ni_dvp) ||
+ (irflag & VIRF_NAMEDDIR) != 0) {
+ error = EINVAL;
+ goto out;
+ }
if (tvp != NULL) {
if (fvp->v_type == VDIR && tvp->v_type != VDIR) {
error = ENOTDIR;
@@ -3893,6 +3917,10 @@
return (error);
goto restart;
}
+ if ((vn_irflag_read(nd.ni_dvp) & VIRF_NAMEDDIR) != 0) {
+ error = EINVAL;
+ goto out;
+ }
VATTR_NULL(&vattr);
vattr.va_type = VDIR;
vattr.va_mode = (mode & ACCESSPERMS) &~ td->td_proc->p_pd->pd_cmask;
@@ -4631,6 +4659,7 @@
struct file *fp;
int fmode, error;
int indx;
+ bool named_attr;
error = priv_check(td, PRIV_VFS_FHOPEN);
if (error != 0)
@@ -4652,6 +4681,19 @@
vfs_unbusy(mp);
if (error != 0)
return (error);
+
+ /*
+ * Check to see if the file handle refers to a named attribute
+ * directory or attribute. If it does, the O_NAMEDATTR flag
+ * must have been specified.
+ */
+ named_attr = (vn_irflag_read(vp) &
+ (VIRF_NAMEDDIR | VIRF_NAMEDATTR)) != 0;
+ if ((named_attr && (fmode & O_NAMEDATTR) == 0) ||
+ (!named_attr && (fmode & O_NAMEDATTR) != 0)) {
+ vput(vp);
+ return (ENOATTR);
+ }
error = falloc_noinstall(td, &fp);
if (error != 0) {
diff --git a/sys/kern/vfs_vnops.c.xattr b/sys/kern/vfs_vnops.c
--- a/sys/kern/vfs_vnops.c.xattr
+++ b/sys/kern/vfs_vnops.c
@@ -208,6 +208,11 @@
res |= OPENREAD;
if ((fmode & FWRITE) != 0)
res |= OPENWRITE;
+ if ((fmode & O_NAMEDATTR) != 0) {
+ res |= OPENNAMED;
+ if ((fmode & O_CREAT) != 0)
+ res |= CREATENAMED;
+ }
if ((vn_open_flags & VN_OPEN_NOAUDIT) == 0)
res |= AUDITVNODE1;
if ((vn_open_flags & VN_OPEN_NOCAPCHECK) != 0)
@@ -261,6 +266,19 @@
if ((error = namei(ndp)) != 0)
return (error);
if (ndp->ni_vp == NULL) {
+ if ((fmode & O_NAMEDATTR) != 0) {
+ if ((ndp->ni_dvp->v_mount->mnt_flag &
+ MNT_NAMEDATTR) == 0)
+ error = EINVAL;
+ else if ((vn_irflag_read(ndp->ni_dvp) &
+ VIRF_NAMEDDIR) == 0)
+ error = ENOENT;
+ if (error != 0) {
+ vp = ndp->ni_dvp;
+ ndp->ni_dvp = NULL;
+ goto bad;
+ }
+ }
VATTR_NULL(vap);
vap->va_type = VREG;
vap->va_mode = cmode;
@@ -315,7 +333,21 @@
error = EEXIST;
goto bad;
}
- if (vp->v_type == VDIR) {
+ if ((fmode & O_NAMEDATTR) != 0) {
+ short irflag;
+
+ irflag = vn_irflag_read(vp);
+ if ((vp->v_mount->mnt_flag &
+ MNT_NAMEDATTR) == 0 ||
+ ((irflag & VIRF_NAMEDATTR) != 0 &&
+ vp->v_type != VREG))
+ error = EINVAL;
+ else if ((irflag & (VIRF_NAMEDDIR |
+ VIRF_NAMEDATTR)) == 0)
+ error = ENOATTR;
+ if (error != 0)
+ goto bad;
+ } else if (vp->v_type == VDIR) {
error = EISDIR;
goto bad;
}
@@ -331,6 +363,11 @@
if ((error = namei(ndp)) != 0)
return (error);
vp = ndp->ni_vp;
+ if ((fmode & O_NAMEDATTR) != 0 && (vp->v_mount->mnt_flag &
+ MNT_NAMEDATTR) == 0) {
+ error = EINVAL;
+ goto bad;
+ }
}
error = vn_open_vnode(vp, fmode, cred, curthread, fp);
if (first_open) {
diff --git a/sys/sys/fcntl.h.xattr b/sys/sys/fcntl.h
--- a/sys/sys/fcntl.h.xattr
+++ b/sys/sys/fcntl.h
@@ -140,6 +140,7 @@
#define O_DSYNC 0x01000000 /* POSIX data sync */
#if __BSD_VISIBLE
#define O_EMPTY_PATH 0x02000000
+#define O_NAMEDATTR 0x04000000 /* NFSv4 named attributes */
#endif
/*
diff --git a/sys/sys/mount.h.xattr b/sys/sys/mount.h
--- a/sys/sys/mount.h.xattr
+++ b/sys/sys/mount.h
@@ -365,6 +365,7 @@
{ MNT_RELOAD, "reload" }, \
{ MNT_FORCE, "force" }, \
{ MNT_SNAPSHOT, "snapshot" }, \
+ { MNT_NAMEDATTR, "named attributes" }, \
{ 0, NULL }
#endif
@@ -390,6 +391,7 @@
#define MNT_SUJ 0x0000000100000000ULL /* using journaled soft updates */
#define MNT_AUTOMOUNTED 0x0000000200000000ULL /* mounted by automountd(8) */
#define MNT_UNTRUSTED 0x0000000800000000ULL /* filesys metadata untrusted */
+#define MNT_NAMEDATTR 0x0000020000000000ULL /* named attributes enabled */
/*
* NFS export related mount flags.
@@ -429,7 +431,7 @@
MNT_IGNORE | MNT_EXPUBLIC | MNT_NOSYMFOLLOW | \
MNT_GJOURNAL | MNT_MULTILABEL | MNT_ACLS | \
MNT_NFS4ACLS | MNT_AUTOMOUNTED | MNT_VERIFIED | \
- MNT_UNTRUSTED)
+ MNT_UNTRUSTED | MNT_NAMEDATTR)
/* Mask of flags that can be updated. */
#define MNT_UPDATEMASK (MNT_NOSUID | MNT_NOEXEC | \
diff --git a/sys/sys/namei.h.xattr b/sys/sys/namei.h
--- a/sys/sys/namei.h.xattr
+++ b/sys/sys/namei.h
@@ -172,14 +172,15 @@
#define OPENREAD 0x00200000 /* open for reading */
#define OPENWRITE 0x00400000 /* open for writing */
#define WANTIOCTLCAPS 0x00800000 /* leave ioctl caps for the caller */
-/* UNUSED 0x01000000 */
+#define OPENNAMED 0x01000000 /* opening a named attribute (dir) */
#define NOEXECCHECK 0x02000000 /* do not perform exec check on dir */
#define MAKEENTRY 0x04000000 /* entry is to be added to name cache */
#define ISSYMLINK 0x08000000 /* symlink needs interpretation */
#define ISLASTCN 0x10000000 /* this is last component of pathname */
#define ISDOTDOT 0x20000000 /* current component name is .. */
#define TRAILINGSLASH 0x40000000 /* path ended in a slash */
-#define PARAMASK 0x7ffffe00 /* mask of parameter descriptors */
+#define CREATENAMED 0x80000000 /* create a named attribute dir */
+#define PARAMASK 0xfffffe00 /* mask of parameter descriptors */
/*
* Flags which must not be passed in by callers.
diff --git a/sys/sys/unistd.h.xattr b/sys/sys/unistd.h
--- a/sys/sys/unistd.h.xattr
+++ b/sys/sys/unistd.h
@@ -154,6 +154,7 @@
#define _PC_MAC_PRESENT 63
#define _PC_ACL_NFS4 64
#define _PC_DEALLOC_PRESENT 65
+#define _PC_NAMEDATTR_ENABLED 66
#endif
/* From OpenSolaris, used by SEEK_DATA/SEEK_HOLE. */
diff --git a/sys/sys/vnode.h.xattr b/sys/sys/vnode.h
--- a/sys/sys/vnode.h.xattr
+++ b/sys/sys/vnode.h
@@ -246,6 +246,8 @@
#define VIRF_MOUNTPOINT 0x0004 /* This vnode is mounted on */
#define VIRF_TEXT_REF 0x0008 /* Executable mappings ref the vnode */
#define VIRF_CROSSMP 0x0010 /* Cross-mp vnode, no locking */
+#define VIRF_NAMEDDIR 0x0020 /* Named attribute directory */
+#define VIRF_NAMEDATTR 0x0040 /* Named attribute */
#define VI_UNUSED0 0x0001 /* unused */
#define VI_MOUNT 0x0002 /* Mount in progress */
@@ -305,9 +307,10 @@
/*
* Flags for va_vaflags.
*/
-#define VA_UTIMES_NULL 0x01 /* utimes argument was NULL */
-#define VA_EXCLUSIVE 0x02 /* exclusive create request */
-#define VA_SYNC 0x04 /* O_SYNC truncation */
+#define VA_UTIMES_NULL 0x01 /* utimes argument was NULL */
+#define VA_EXCLUSIVE 0x02 /* exclusive create request */
+#define VA_SYNC 0x04 /* O_SYNC truncation */
+#define VA_NAMEDATTR_TYPE 0x08 /* vnode is for named attribute */
/*
* Flags for ioflag. (high 16 bits used to ask for read-ahead and

File Metadata

Mime Type
text/plain
Expires
Wed, Jul 8, 3:04 AM (21 h, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34827051
Default Alt Text
D49583.id153010.diff (9 KB)

Event Timeline