uint64_t xfs_panic_mask; /* set to cause more panics */
unsigned long xfs_physmem;
-/*
- * restricted_chown = 1 bsd style chown(2), only super-user can give away files
- * restricted_chown = 0 sysV style chown(2), non super-user can give away files
- */
-int restricted_chown = 1;
-
/*
* Used to serialize atomicIncWithWrap.
*/
extern uint64_t xfs_panic_mask; /* set to cause more panics */
-extern int restricted_chown;
extern unsigned long xfs_physmem;
extern struct cred *sys_cred;
bzero(&va, sizeof(va));
va.va_type = VLNK;
- va.va_mode = 0777 & ~current->fs->umask;
- va.va_mask = AT_TYPE|AT_MODE; /* AT_PROJID? */
+ va.va_mode = irix_symlink_mode ? 0777 & ~current->fs->umask : S_IRWXUGO;
+ va.va_mask = AT_TYPE|AT_MODE;
error = 0;
- VOP_SYMLINK(dvp, dentry, &va, (char *)symname,
- &cvp, NULL, error);
+ VOP_SYMLINK(dvp, dentry, &va, (char *)symname, &cvp, NULL, error);
if (!error) {
ASSERT(cvp);
ASSERT(cvp->v_type == VLNK);
}
/*
- * careful here - this function can get called recusively, so
+ * careful here - this function can get called recursively, so
* we need to be very careful about how much stack we use.
* uio is kmalloced for this reason...
*/
#define STATIC static
#endif
+#define restricted_chown xfs_params.restrict_chown
+#define irix_sgid_inherit xfs_params.sgid_inherit
+#define irix_symlink_mode xfs_params.symlink_mode
+
typedef struct xfs_dirent { /* data from readdir() */
xfs_ino_t d_ino; /* inode number of entry */
xfs_off_t d_off; /* offset of disk directory entry */
#define MNTOPT_SUNIT "sunit" /* data volume stripe unit */
#define MNTOPT_SWIDTH "swidth" /* data volume stripe width */
#define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */
-#define MNTOPT_OSYNCISDSYNC "osyncisdsync" /* o_sync == o_dsync on this fs */
- /* (this is now the default!) */
#define MNTOPT_OSYNCISOSYNC "osyncisosync" /* o_sync is REALLY o_sync */
#define MNTOPT_QUOTA "quota" /* disk quotas */
#define MNTOPT_MRQUOTA "mrquota" /* don't turnoff if SB has quotas on */
#define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */
#define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */
#define MNTOPT_NOUUID "nouuid" /* Ignore FS uuid */
-#define MNTOPT_IRIXSGID "irixsgid" /* Irix-style sgid inheritance */
#define MNTOPT_NOLOGFLUSH "nologflush" /* Don't use hard flushes in
log writing */
#define MNTOPT_MTPT "mtpt" /* filesystem mount point */
args->iosizelog = (uint8_t) iosize;
} else if (!strcmp(this_char, MNTOPT_WSYNC)) {
args->flags |= XFSMNT_WSYNC;
- } else if (!strcmp(this_char, MNTOPT_OSYNCISDSYNC)) {
- /* no-op, this is now the default */
-printk("XFS: osyncisdsync is now the default, and will soon be deprecated.\n");
} else if (!strcmp(this_char, MNTOPT_OSYNCISOSYNC)) {
args->flags |= XFSMNT_OSYNCISOSYNC;
} else if (!strcmp(this_char, MNTOPT_NORECOVERY)) {
dswidth = simple_strtoul(value, &eov, 10);
} else if (!strcmp(this_char, MNTOPT_NOUUID)) {
args->flags |= XFSMNT_NOUUID;
- } else if (!strcmp(this_char, MNTOPT_IRIXSGID)) {
- args->flags |= XFSMNT_IRIXSGID;
} else if (!strcmp(this_char, MNTOPT_NOLOGFLUSH)) {
args->flags |= XFSMNT_NOLOGFLUSH;
+ } else if (!strcmp(this_char, "osyncisdsync")) {
+ /* no-op, this is now the default */
+printk("XFS: osyncisdsync is now the default, option is deprecated.\n");
+ } else if (!strcmp(this_char, "irixsgid")) {
+printk("XFS: irixsgid is now a sysctl(2) variable, option is deprecated.\n");
} else {
printk("XFS: unknown mount option [%s].\n", this_char);
return rval;
return 0;
}
+STATIC int
+xfs_showargs(
+ struct vfs *vfsp,
+ struct seq_file *m)
+{
+ static struct proc_xfs_info {
+ int flag;
+ char *str;
+ } xfs_info[] = {
+ /* the few simple ones we can get from the mount struct */
+ { XFS_MOUNT_NOALIGN, "," MNTOPT_NOALIGN },
+ { XFS_MOUNT_NORECOVERY, "," MNTOPT_NORECOVERY },
+ { XFS_MOUNT_OSYNCISOSYNC, "," MNTOPT_OSYNCISOSYNC },
+ { XFS_MOUNT_NOUUID, "," MNTOPT_NOUUID },
+ { 0, NULL }
+ };
+ struct proc_xfs_info *xfs_infop;
+ struct xfs_mount *mp = XFS_BHVTOM(vfsp->vfs_fbhv);
+
+ for (xfs_infop = xfs_info; xfs_infop->flag; xfs_infop++) {
+ if (mp->m_flags & xfs_infop->flag)
+ seq_puts(m, xfs_infop->str);
+ }
+
+ if (mp->m_qflags & XFS_UQUOTA_ACCT) {
+ (mp->m_qflags & XFS_UQUOTA_ENFD) ?
+ seq_puts(m, "," MNTOPT_UQUOTA) :
+ seq_puts(m, "," MNTOPT_UQUOTANOENF);
+ }
+
+ if (mp->m_qflags & XFS_GQUOTA_ACCT) {
+ (mp->m_qflags & XFS_GQUOTA_ENFD) ?
+ seq_puts(m, "," MNTOPT_GQUOTA) :
+ seq_puts(m, "," MNTOPT_GQUOTANOENF);
+ }
+
+ if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)
+ seq_printf(m, "," MNTOPT_BIOSIZE "=%d", mp->m_writeio_log);
+
+ if (mp->m_logbufs > 0)
+ seq_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs);
+
+ if (mp->m_logbsize > 0)
+ seq_printf(m, "," MNTOPT_LOGBSIZE "=%d", mp->m_logbsize);
+
+ if (mp->m_ddev_targp->pbr_dev != mp->m_logdev_targp->pbr_dev)
+ seq_printf(m, "," MNTOPT_LOGDEV "=%s",
+ bdevname(mp->m_logdev_targp->pbr_bdev));
+
+ if (mp->m_rtdev_targp &&
+ mp->m_ddev_targp->pbr_dev != mp->m_rtdev_targp->pbr_dev)
+ seq_printf(m, "," MNTOPT_RTDEV "=%s",
+ bdevname(mp->m_rtdev_targp->pbr_bdev));
+
+ if (mp->m_dalign > 0)
+ seq_printf(m, "," MNTOPT_SUNIT "=%d",
+ (int)XFS_FSB_TO_BB(mp, mp->m_dalign));
+
+ if (mp->m_swidth > 0)
+ seq_printf(m, "," MNTOPT_SWIDTH "=%d",
+ (int)XFS_FSB_TO_BB(mp, mp->m_swidth));
+
+ if (vfsp->vfs_flag & VFS_DMI)
+ seq_puts(m, "," MNTOPT_DMAPI);
+
+ return 0;
+}
+
STATIC kmem_cache_t * linvfs_inode_cachep;
struct seq_file *m,
struct vfsmount *mnt)
{
- vfs_t *vfsp;
- xfs_mount_t *mp;
- static struct proc_xfs_info {
- int flag;
- char *str;
- } xfs_info[] = {
- /* the few simple ones we can get from the mount struct */
- { XFS_MOUNT_NOALIGN, ",noalign" },
- { XFS_MOUNT_NORECOVERY, ",norecovery" },
- { XFS_MOUNT_OSYNCISOSYNC, ",osyncisosync" },
- { XFS_MOUNT_NOUUID, ",nouuid" },
- { XFS_MOUNT_IRIXSGID, ",irixsgid" },
- { 0, NULL }
- };
- struct proc_xfs_info *xfs_infop;
-
- vfsp = LINVFS_GET_VFS(mnt->mnt_sb);
- mp = XFS_BHVTOM(vfsp->vfs_fbhv);
-
- for (xfs_infop = xfs_info; xfs_infop->flag; xfs_infop++) {
- if (mp->m_flags & xfs_infop->flag)
- seq_puts(m, xfs_infop->str);
- }
-
- if (mp->m_qflags & XFS_UQUOTA_ACCT) {
- seq_puts(m, ",uquota");
- if (!(mp->m_qflags & XFS_UQUOTA_ENFD))
- seq_puts(m, ",uqnoenforce");
- }
-
- if (mp->m_qflags & XFS_GQUOTA_ACCT) {
- seq_puts(m, ",gquota");
- if (!(mp->m_qflags & XFS_GQUOTA_ENFD))
- seq_puts(m, ",gqnoenforce");
- }
-
- if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)
- seq_printf(m, ",biosize=%d", mp->m_writeio_log);
-
- if (mp->m_logbufs > 0)
- seq_printf(m, ",logbufs=%d", mp->m_logbufs);
-
- if (mp->m_logbsize > 0)
- seq_printf(m, ",logbsize=%d", mp->m_logbsize);
-
- if (mp->m_ddev_targp->pbr_dev != mp->m_logdev_targp->pbr_dev)
- seq_printf(m, ",logdev=%s",
- bdevname(mp->m_logdev_targp->pbr_bdev));
+ vfs_t *vfsp = LINVFS_GET_VFS(mnt->mnt_sb);
- if (mp->m_rtdev_targp &&
- mp->m_ddev_targp->pbr_dev != mp->m_rtdev_targp->pbr_dev)
- seq_printf(m, ",rtdev=%s",
- bdevname(mp->m_rtdev_targp->pbr_bdev));
-
- if (mp->m_dalign > 0)
- seq_printf(m, ",sunit=%d",
- (int)XFS_FSB_TO_BB(mp, mp->m_dalign));
-
- if (mp->m_swidth > 0)
- seq_printf(m, ",swidth=%d",
- (int)XFS_FSB_TO_BB(mp, mp->m_swidth));
-
- if (vfsp->vfs_flag & VFS_DMI)
- seq_puts(m, ",dmapi");
-
- return 0;
+ return xfs_showargs(vfsp, m);
}
STATIC struct super_operations linvfs_sops = {
#include <linux/proc_fs.h>
/*
- * Tunable xfs parameters
+ * Tunable XFS parameters
*/
extern struct xfsstats xfsstats;
-unsigned long xfs_min[XFS_PARAM] = { 0, 0, 0 };
-unsigned long xfs_max[XFS_PARAM] = { XFS_REFCACHE_SIZE_MAX, XFS_REFCACHE_SIZE_MAX, 1 };
+STATIC ulong xfs_min[XFS_PARAM] = { \
+ 0, 0, 0, 0, 0, 0 };
+STATIC ulong xfs_max[XFS_PARAM] = { \
+ XFS_REFCACHE_SIZE_MAX, XFS_REFCACHE_SIZE_MAX, 1, 1, 1, 1 };
-xfs_param_t xfs_params = { 128, 32, 0 };
+xfs_param_t xfs_params = { 128, 32, 0, 1, 0, 0 };
static struct ctl_table_header *xfs_table_header;
-/* proc handlers */
-extern void xfs_refcache_resize(int xfs_refcache_new_size);
+/* Custom proc handlers */
-static int
-xfs_refcache_resize_proc_handler(ctl_table *ctl, int write, struct file * filp,
- void *buffer, size_t *lenp)
+STATIC int
+xfs_refcache_resize_proc_handler(
+ ctl_table *ctl,
+ int write,
+ struct file *filp,
+ void *buffer,
+ size_t *lenp)
{
- int ret;
- int *valp = ctl->data;
- int xfs_refcache_new_size;
- int xfs_refcache_old_size = *valp;
+ int ret, *valp = ctl->data;
+ int xfs_refcache_new_size;
+ int xfs_refcache_old_size = *valp;
ret = proc_doulongvec_minmax(ctl, write, filp, buffer, lenp);
xfs_refcache_new_size = *valp;
return ret;
}
-static int
-xfs_stats_clear_proc_handler(ctl_table *ctl, int write, struct file * filp,
- void *buffer, size_t *lenp)
+STATIC int
+xfs_stats_clear_proc_handler(
+ ctl_table *ctl,
+ int write,
+ struct file *filp,
+ void *buffer,
+ size_t *lenp)
{
- int ret;
- int *valp = ctl->data;
+ int ret, *valp = ctl->data;
__uint32_t vn_active;
ret = proc_doulongvec_minmax(ctl, write, filp, buffer, lenp);
return ret;
}
-static ctl_table xfs_table[] = {
+STATIC ctl_table xfs_table[] = {
{XFS_REFCACHE_SIZE, "refcache_size", &xfs_params.refcache_size,
sizeof(ulong), 0644, NULL, &xfs_refcache_resize_proc_handler,
&sysctl_intvec, NULL, &xfs_min[0], &xfs_max[0]},
sizeof(ulong), 0644, NULL, &xfs_stats_clear_proc_handler,
&sysctl_intvec, NULL, &xfs_min[2], &xfs_max[2]},
+ {XFS_RESTRICT_CHOWN, "restrict_chown", &xfs_params.restrict_chown,
+ sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax,
+ &sysctl_intvec, NULL, &xfs_min[3], &xfs_max[3]},
+
+ {XFS_SGID_INHERIT, "irix_sgid_inherit", &xfs_params.sgid_inherit,
+ sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax,
+ &sysctl_intvec, NULL, &xfs_min[4], &xfs_max[4]},
+
+ {XFS_SYMLINK_MODE, "irix_symlink_mode", &xfs_params.symlink_mode,
+ sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax,
+ &sysctl_intvec, NULL, &xfs_min[5], &xfs_max[5]},
+
{0}
};
-static ctl_table xfs_dir_table[] = {
+STATIC ctl_table xfs_dir_table[] = {
{FS_XFS, "xfs", NULL, 0, 0555, xfs_table},
{0}
};
-static ctl_table xfs_root_table[] = {
+STATIC ctl_table xfs_root_table[] = {
{CTL_FS, "fs", NULL, 0, 0555, xfs_dir_table},
{0}
};
* Tunable xfs parameters
*/
-#define XFS_PARAM 3
+#define XFS_PARAM (sizeof(struct xfs_param) / sizeof(ulong))
typedef struct xfs_param {
- ulong refcache_size; /* Size of nfs refcache */
- ulong refcache_purge; /* # of entries to purge each time */
- ulong stats_clear; /* reset all xfs stats to 0 */
+ ulong refcache_size; /* Size of NFS reference cache. */
+ ulong refcache_purge; /* # of entries to purge each time. */
+ ulong stats_clear; /* Reset all XFS statistics to zero. */
+ ulong restrict_chown; /* Root/non-root can give away files. */
+ ulong sgid_inherit; /* Inherit ISGID bit if process' GID is */
+ /* not a member of the parent dir GID. */
+ ulong symlink_mode; /* Symlink creat mode affected by umask. */
} xfs_param_t;
enum {
XFS_REFCACHE_SIZE = 1,
XFS_REFCACHE_PURGE = 2,
XFS_STATS_CLEAR = 3,
+ XFS_RESTRICT_CHOWN = 4,
+ XFS_SGID_INHERIT = 5,
+ XFS_SYMLINK_MODE = 6,
};
extern xfs_param_t xfs_params;
#define XFSMNT_NOUUID 0x01000000 /* Ignore fs uuid */
#define XFSMNT_32BITINODES 0x02000000 /* restrict inodes to 32
* bits of address space */
-#define XFSMNT_IRIXSGID 0x04000000 /* Irix-style sgid inheritance */
-#define XFSMNT_NOLOGFLUSH 0x08000000 /* Don't flush for log blocks */
+#define XFSMNT_NOLOGFLUSH 0x04000000 /* Don't flush for log blocks */
/* Did we get any args for CXFS to consume? */
#define XFSARGS_FOR_CXFSARR(ap) \
/*
* If the group ID of the new file does not match the effective group
- * ID or one of the supplementary group IDs, the ISGID bit is
- * cleared if the "irixsgid" mount option is set.
+ * ID or one of the supplementary group IDs, the ISGID bit is cleared
+ * (and only if the irix_sgid_inherit compatibility variable is set).
*/
- if (ip->i_d.di_mode & ISGID) {
- if (!in_group_p((gid_t)ip->i_d.di_gid)
- && (ip->i_mount->m_flags & XFS_MOUNT_IRIXSGID)) {
- ip->i_d.di_mode &= ~ISGID;
- }
+ if ((irix_sgid_inherit) &&
+ (ip->i_d.di_mode & ISGID) &&
+ (!in_group_p((gid_t)ip->i_d.di_gid))) {
+ ip->i_d.di_mode &= ~ISGID;
}
ip->i_d.di_size = 0;
xfs_extlen_t xg_count_fsb;
} xfs_gap_t;
-/*
- * This structure is used to hold common pieces of the buffer
- * and file for xfs_dio_write and xfs_dio_read.
- */
-typedef struct xfs_dio {
- struct xfs_buf *xd_bp;
- bhv_desc_t *xd_bdp;
- struct xfs_inode *xd_ip;
- struct xfs_iocore *xd_io;
- struct cred *xd_cr;
- struct pm *xd_pmp;
- int xd_blkalgn;
- int xd_ioflag;
- xfs_off_t xd_start;
- size_t xd_length;
-} xfs_dio_t;
-
typedef struct dm_attrs_s {
__uint32_t da_dmevmask; /* DMIG event mask */
__uint16_t da_dmstate; /* DMIG state info */
struct xfs_perag;
struct xfs_quotainfo;
struct xfs_iocore;
-struct xfs_dio;
struct xfs_bmbt_irec;
struct xfs_bmap_free;
* minimize the number of memory indirections involved.
*/
-typedef int (*xfs_dio_write_t)(struct xfs_dio *);
-typedef int (*xfs_dio_read_t)(struct xfs_dio *);
-typedef int (*xfs_strat_write_t)(struct xfs_iocore *, struct xfs_buf *);
typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *,
xfs_fileoff_t, xfs_filblks_t, int,
xfs_fsblock_t *, xfs_extlen_t,
struct xfs_bmbt_irec *, int *,
struct xfs_bmap_free *);
typedef int (*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *);
-typedef int (*xfs_rsync_t)(void *, int, xfs_off_t, xfs_off_t);
-typedef uint (*xfs_lck_map_shared_t)(void *);
typedef void (*xfs_lock_t)(void *, uint);
typedef void (*xfs_lock_demote_t)(void *, uint);
typedef int (*xfs_lock_nowait_t)(void *, uint);
typedef void (*xfs_unlk_t)(void *, unsigned int);
typedef void (*xfs_chgtime_t)(void *, int);
typedef xfs_fsize_t (*xfs_size_t)(void *);
-typedef xfs_fsize_t (*xfs_setsize_t)(void *, xfs_off_t);
typedef xfs_fsize_t (*xfs_lastbyte_t)(void *);
typedef struct xfs_ioops {
#define XFS_MOUNT_NOUUID 0x00004000 /* ignore uuid during mount */
#define XFS_MOUNT_32BITINODES 0x00008000 /* do not create inodes above
* 32 bits in size */
-#define XFS_MOUNT_IRIXSGID 0x00010000 /* Irix-style sgid inheritance */
-#define XFS_MOUNT_NOLOGFLUSH 0x00020000
+#define XFS_MOUNT_NOLOGFLUSH 0x00010000
/*
* Flags for m_cxfstype
struct xfs_iocore;
struct xfs_mount;
struct xfs_trans;
-struct xfs_dio;
struct pm;
/*
if (1 || ap->flags & XFSMNT_32BITINODES)
mp->m_flags |= XFS_MOUNT_32BITINODES;
- if (ap->flags & XFSMNT_IRIXSGID)
- mp->m_flags |= XFS_MOUNT_IRIXSGID;
-
if (ap->flags & XFSMNT_IOSIZE) {
if (ap->iosizelog > XFS_MAX_IO_LOG ||
ap->iosizelog < XFS_MIN_IO_LOG) {
"OSYNC", /* 0x2000 */
"NOUUID", /* 0x4000 */
"32BIT", /* 0x8000 */
- "IRIXSGID", /* 0x10000 */
- "NOLOGFLUSH", /* 0x20000 */
+ "NOLOGFLUSH", /* 0x10000 */
0
};