Add the new parent attribute type. XFS_ATTR_PARENT is used only for parent pointer entries; it uses reserved blocks like XFS_ATTR_ROOT. --- fs/xfs/xfs_attr.c | 20 ++++++++++++-------- fs/xfs/xfs_attr.h | 2 ++ fs/xfs/xfs_da_format.h | 12 ++++++++---- fs/xfs/xfs_fs.h | 1 + fs/xfs/xfs_fsops.c | 4 +++- 6 files changed, 65 insertions(+), 13 deletions(-) Index: b/fs/xfs/xfs_attr.c =================================================================== --- a/fs/xfs/xfs_attr.c +++ b/fs/xfs/xfs_attr.c @@ -234,7 +234,7 @@ xfs_attr_set_int( int error, err2, committed; struct xfs_mount *mp = dp->i_mount; struct xfs_trans_res tres; - int rsvd = (flags & ATTR_ROOT) != 0; + int rsvd = (flags & (ATTR_ROOT | ATTR_PARENT)) != 0; int local; /* @@ -444,18 +444,22 @@ xfs_attr_set( int flags) { int error; - struct xfs_name xname; + struct xfs_name xname, *xnamep; XFS_STATS_INC(xs_attr_set); if (XFS_FORCED_SHUTDOWN(dp->i_mount)) return (EIO); - error = xfs_attr_name_to_xname(&xname, name); - if (error) - return error; - - return xfs_attr_set_int(dp, &xname, value, valuelen, flags); + if ((flags & ATTR_PARENT) == 0) { + error = xfs_attr_name_to_xname(&xname, name); + if (error) + return error; + xnamep = &xname; + } else + xnamep = (struct xfs_name *) name; + return xfs_attr_set_int(dp, xnamep, value, valuelen, flags); + } /* @@ -516,7 +520,7 @@ xfs_attr_remove_int(xfs_inode_t *dp, str * operation if necessary */ - if (flags & ATTR_ROOT) + if (flags & (ATTR_ROOT | ATTR_PARENT)) args.trans->t_flags |= XFS_TRANS_RESERVE; error = xfs_trans_reserve(args.trans, &M_RES(mp)->tr_attrrm, Index: b/fs/xfs/xfs_attr.h =================================================================== --- a/fs/xfs/xfs_attr.h +++ b/fs/xfs/xfs_attr.h @@ -44,6 +44,7 @@ struct xfs_attr_list_context; #define ATTR_SECURE 0x0008 /* use attrs in security namespace */ #define ATTR_CREATE 0x0010 /* pure create: fail if attr already exists */ #define ATTR_REPLACE 0x0020 /* pure set: fail if attr does not exist */ +#define ATTR_PARENT 0x0040 /* use attrs in parent namespace */ #define ATTR_KERNOTIME 0x1000 /* [kernel] don't update inode timestamps */ #define ATTR_KERNOVAL 0x2000 /* [kernel] get attr size only, not value */ @@ -55,6 +56,7 @@ struct xfs_attr_list_context; { ATTR_SECURE, "SECURE" }, \ { ATTR_CREATE, "CREATE" }, \ { ATTR_REPLACE, "REPLACE" }, \ + { ATTR_PARENT, "PARENT" }, \ { ATTR_KERNOTIME, "KERNOTIME" }, \ { ATTR_KERNOVAL, "KERNOVAL" } Index: b/fs/xfs/xfs_da_format.h =================================================================== --- a/fs/xfs/xfs_da_format.h +++ b/fs/xfs/xfs_da_format.h @@ -895,24 +895,28 @@ struct xfs_attr3_icleaf_hdr { #define XFS_ATTR_LOCAL_BIT 0 /* attr is stored locally */ #define XFS_ATTR_ROOT_BIT 1 /* limit access to trusted attrs */ #define XFS_ATTR_SECURE_BIT 2 /* limit access to secure attrs */ +#define XFS_ATTR_PARENT_BIT 3 /* parent pointer secure attrs */ #define XFS_ATTR_INCOMPLETE_BIT 7 /* attr in middle of create/delete */ #define XFS_ATTR_LOCAL (1 << XFS_ATTR_LOCAL_BIT) #define XFS_ATTR_ROOT (1 << XFS_ATTR_ROOT_BIT) #define XFS_ATTR_SECURE (1 << XFS_ATTR_SECURE_BIT) +#define XFS_ATTR_PARENT (1 << XFS_ATTR_PARENT_BIT) #define XFS_ATTR_INCOMPLETE (1 << XFS_ATTR_INCOMPLETE_BIT) /* * Conversion macros for converting namespace bits from argument flags * to ondisk flags. */ -#define XFS_ATTR_NSP_ARGS_MASK (ATTR_ROOT | ATTR_SECURE) -#define XFS_ATTR_NSP_ONDISK_MASK (XFS_ATTR_ROOT | XFS_ATTR_SECURE) +#define XFS_ATTR_NSP_ARGS_MASK (ATTR_ROOT | ATTR_SECURE | XFS_ATTR_PARENT) +#define XFS_ATTR_NSP_ONDISK_MASK (XFS_ATTR_ROOT | XFS_ATTR_SECURE | XFS_ATTR_PARENT) #define XFS_ATTR_NSP_ONDISK(flags) ((flags) & XFS_ATTR_NSP_ONDISK_MASK) #define XFS_ATTR_NSP_ARGS(flags) ((flags) & XFS_ATTR_NSP_ARGS_MASK) #define XFS_ATTR_NSP_ARGS_TO_ONDISK(x) (((x) & ATTR_ROOT ? XFS_ATTR_ROOT : 0) |\ - ((x) & ATTR_SECURE ? XFS_ATTR_SECURE : 0)) + ((x) & ATTR_SECURE ? XFS_ATTR_SECURE : 0) | \ + ((x) & ATTR_PARENT ? XFS_ATTR_PARENT : 0)) #define XFS_ATTR_NSP_ONDISK_TO_ARGS(x) (((x) & XFS_ATTR_ROOT ? ATTR_ROOT : 0) |\ - ((x) & XFS_ATTR_SECURE ? ATTR_SECURE : 0)) + ((x) & XFS_ATTR_SECURE ? ATTR_SECURE : 0) | \ + ((x) & XFS_ATTR_PARENT ? ATTR_PARENT : 0)) /* * Alignment for namelist and valuelist entries (since they are mixed Index: b/fs/xfs/xfs_fs.h =================================================================== --- a/fs/xfs/xfs_fs.h +++ b/fs/xfs/xfs_fs.h @@ -238,6 +238,7 @@ typedef struct xfs_fsop_resblks { #define XFS_FSOP_GEOM_FLAGS_LAZYSB 0x4000 /* lazy superblock counters */ #define XFS_FSOP_GEOM_FLAGS_V5SB 0x8000 /* version 5 superblock */ #define XFS_FSOP_GEOM_FLAGS_FTYPE 0x10000 /* inode directory types */ +#define XFS_FSOP_GEOM_FLAGS_PARENT 0x20000 /* parent inode support */ /* * Minimum and maximum sizes need for growth checks. Index: b/fs/xfs/xfs_fsops.c =================================================================== --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -104,7 +104,9 @@ xfs_fs_geometry( (xfs_sb_version_hascrc(&mp->m_sb) ? XFS_FSOP_GEOM_FLAGS_V5SB : 0) | (xfs_sb_version_hasftype(&mp->m_sb) ? - XFS_FSOP_GEOM_FLAGS_FTYPE : 0); + XFS_FSOP_GEOM_FLAGS_FTYPE : 0) | + (xfs_sb_version_hasparent(&mp->m_sb) ? + XFS_FSOP_GEOM_FLAGS_PARENT : 0); geo->logsectsize = xfs_sb_version_hassector(&mp->m_sb) ? mp->m_sb.sb_logsectsize : BBSIZE; geo->rtsectsize = mp->m_sb.sb_blocksize; _______________________________________________ xfs mailing list xfs@xxxxxxxxxxx http://oss.sgi.com/mailman/listinfo/xfs