Commit b8a327be authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://oss.sgi.com:8090/xfs/xfs-pull

* 'for-linus' of git://oss.sgi.com:8090/xfs/xfs-pull: (64 commits)
  [XFS] Remove vn_revalidate calls in xfs.
  [XFS] Now that xfs_setattr is only used for attributes set from ->setattr
  [XFS] xfs_setattr currently doesn't just handle the attributes set through
  [XFS] fix use after free with external logs or real-time devices
  [XFS] A bug was found in xfs_bmap_add_extent_unwritten_real(). In a
  [XFS] fix compilation without CONFIG_PROC_FS
  [XFS] s/XFS_PURGE_INODE/IRELE/g s/VN_HOLD(XFS_ITOV())/IHOLD()/
  [XFS] fix mount option parsing in remount
  [XFS] Disable queue flag test in barrier check.
  [XFS] streamline init/exit path
  [XFS] Fix up problem when CONFIG_XFS_POSIX_ACL is not set and yet we still
  [XFS] Don't assert if trying to mount with blocksize > pagesize
  [XFS] Don't update mtime on rename source
  [XFS] Allow xfs_bmbt_split() to fallback to the lowspace allocator
  [XFS] Restore the lowspace extent allocator algorithm
  [XFS] use minleft when allocating in xfs_bmbt_split()
  [XFS] attrmulti cleanup
  [XFS] Check for invalid flags in xfs_attrlist_by_handle.
  [XFS] Fix CI lookup in leaf-form directories
  [XFS] Use the generic xattr methods.
  ...
parents 46bd58ea f13fae2d
...@@ -1220,6 +1220,107 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry) ...@@ -1220,6 +1220,107 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
return new; return new;
} }
/**
* d_add_ci - lookup or allocate new dentry with case-exact name
* @inode: the inode case-insensitive lookup has found
* @dentry: the negative dentry that was passed to the parent's lookup func
* @name: the case-exact name to be associated with the returned dentry
*
* This is to avoid filling the dcache with case-insensitive names to the
* same inode, only the actual correct case is stored in the dcache for
* case-insensitive filesystems.
*
* For a case-insensitive lookup match and if the the case-exact dentry
* already exists in in the dcache, use it and return it.
*
* If no entry exists with the exact case name, allocate new dentry with
* the exact case, and return the spliced entry.
*/
struct dentry *d_add_ci(struct inode *inode, struct dentry *dentry,
struct qstr *name)
{
int error;
struct dentry *found;
struct dentry *new;
/* Does a dentry matching the name exist already? */
found = d_hash_and_lookup(dentry->d_parent, name);
/* If not, create it now and return */
if (!found) {
new = d_alloc(dentry->d_parent, name);
if (!new) {
error = -ENOMEM;
goto err_out;
}
found = d_splice_alias(inode, new);
if (found) {
dput(new);
return found;
}
return new;
}
/* Matching dentry exists, check if it is negative. */
if (found->d_inode) {
if (unlikely(found->d_inode != inode)) {
/* This can't happen because bad inodes are unhashed. */
BUG_ON(!is_bad_inode(inode));
BUG_ON(!is_bad_inode(found->d_inode));
}
/*
* Already have the inode and the dentry attached, decrement
* the reference count to balance the iget() done
* earlier on. We found the dentry using d_lookup() so it
* cannot be disconnected and thus we do not need to worry
* about any NFS/disconnectedness issues here.
*/
iput(inode);
return found;
}
/*
* Negative dentry: instantiate it unless the inode is a directory and
* has a 'disconnected' dentry (i.e. IS_ROOT and DCACHE_DISCONNECTED),
* in which case d_move() that in place of the found dentry.
*/
if (!S_ISDIR(inode->i_mode)) {
/* Not a directory; everything is easy. */
d_instantiate(found, inode);
return found;
}
spin_lock(&dcache_lock);
if (list_empty(&inode->i_dentry)) {
/*
* Directory without a 'disconnected' dentry; we need to do
* d_instantiate() by hand because it takes dcache_lock which
* we already hold.
*/
list_add(&found->d_alias, &inode->i_dentry);
found->d_inode = inode;
spin_unlock(&dcache_lock);
security_d_instantiate(found, inode);
return found;
}
/*
* Directory with a 'disconnected' dentry; get a reference to the
* 'disconnected' dentry.
*/
new = list_entry(inode->i_dentry.next, struct dentry, d_alias);
dget_locked(new);
spin_unlock(&dcache_lock);
/* Do security vodoo. */
security_d_instantiate(found, inode);
/* Move new in place of found. */
d_move(new, found);
/* Balance the iget() we did above. */
iput(inode);
/* Throw away found. */
dput(found);
/* Use new as the actual dentry. */
return new;
err_out:
iput(inode);
return ERR_PTR(error);
}
/** /**
* d_lookup - search for a dentry * d_lookup - search for a dentry
...@@ -2254,6 +2355,7 @@ EXPORT_SYMBOL(d_path); ...@@ -2254,6 +2355,7 @@ EXPORT_SYMBOL(d_path);
EXPORT_SYMBOL(d_prune_aliases); EXPORT_SYMBOL(d_prune_aliases);
EXPORT_SYMBOL(d_rehash); EXPORT_SYMBOL(d_rehash);
EXPORT_SYMBOL(d_splice_alias); EXPORT_SYMBOL(d_splice_alias);
EXPORT_SYMBOL(d_add_ci);
EXPORT_SYMBOL(d_validate); EXPORT_SYMBOL(d_validate);
EXPORT_SYMBOL(dget_locked); EXPORT_SYMBOL(dget_locked);
EXPORT_SYMBOL(dput); EXPORT_SYMBOL(dput);
......
...@@ -106,7 +106,8 @@ xfs-y += $(addprefix $(XFS_LINUX)/, \ ...@@ -106,7 +106,8 @@ xfs-y += $(addprefix $(XFS_LINUX)/, \
xfs_iops.o \ xfs_iops.o \
xfs_lrw.o \ xfs_lrw.o \
xfs_super.o \ xfs_super.o \
xfs_vnode.o) xfs_vnode.o \
xfs_xattr.o)
# Objects in support/ # Objects in support/
xfs-y += $(addprefix support/, \ xfs-y += $(addprefix support/, \
......
...@@ -90,7 +90,7 @@ kmem_zalloc_greedy(size_t *size, size_t minsize, size_t maxsize, ...@@ -90,7 +90,7 @@ kmem_zalloc_greedy(size_t *size, size_t minsize, size_t maxsize,
} }
void void
kmem_free(void *ptr, size_t size) kmem_free(const void *ptr)
{ {
if (!is_vmalloc_addr(ptr)) { if (!is_vmalloc_addr(ptr)) {
kfree(ptr); kfree(ptr);
...@@ -100,7 +100,7 @@ kmem_free(void *ptr, size_t size) ...@@ -100,7 +100,7 @@ kmem_free(void *ptr, size_t size)
} }
void * void *
kmem_realloc(void *ptr, size_t newsize, size_t oldsize, kmem_realloc(const void *ptr, size_t newsize, size_t oldsize,
unsigned int __nocast flags) unsigned int __nocast flags)
{ {
void *new; void *new;
...@@ -110,7 +110,7 @@ kmem_realloc(void *ptr, size_t newsize, size_t oldsize, ...@@ -110,7 +110,7 @@ kmem_realloc(void *ptr, size_t newsize, size_t oldsize,
if (new) if (new)
memcpy(new, ptr, memcpy(new, ptr,
((oldsize < newsize) ? oldsize : newsize)); ((oldsize < newsize) ? oldsize : newsize));
kmem_free(ptr, oldsize); kmem_free(ptr);
} }
return new; return new;
} }
......
...@@ -57,8 +57,8 @@ kmem_flags_convert(unsigned int __nocast flags) ...@@ -57,8 +57,8 @@ kmem_flags_convert(unsigned int __nocast flags)
extern void *kmem_alloc(size_t, unsigned int __nocast); extern void *kmem_alloc(size_t, unsigned int __nocast);
extern void *kmem_zalloc(size_t, unsigned int __nocast); extern void *kmem_zalloc(size_t, unsigned int __nocast);
extern void *kmem_zalloc_greedy(size_t *, size_t, size_t, unsigned int __nocast); extern void *kmem_zalloc_greedy(size_t *, size_t, size_t, unsigned int __nocast);
extern void *kmem_realloc(void *, size_t, size_t, unsigned int __nocast); extern void *kmem_realloc(const void *, size_t, size_t, unsigned int __nocast);
extern void kmem_free(void *, size_t); extern void kmem_free(const void *);
/* /*
* Zone interfaces * Zone interfaces
......
...@@ -409,7 +409,6 @@ xfs_start_buffer_writeback( ...@@ -409,7 +409,6 @@ xfs_start_buffer_writeback(
STATIC void STATIC void
xfs_start_page_writeback( xfs_start_page_writeback(
struct page *page, struct page *page,
struct writeback_control *wbc,
int clear_dirty, int clear_dirty,
int buffers) int buffers)
{ {
...@@ -858,7 +857,7 @@ xfs_convert_page( ...@@ -858,7 +857,7 @@ xfs_convert_page(
done = 1; done = 1;
} }
} }
xfs_start_page_writeback(page, wbc, !page_dirty, count); xfs_start_page_writeback(page, !page_dirty, count);
} }
return done; return done;
...@@ -1130,7 +1129,7 @@ xfs_page_state_convert( ...@@ -1130,7 +1129,7 @@ xfs_page_state_convert(
SetPageUptodate(page); SetPageUptodate(page);
if (startio) if (startio)
xfs_start_page_writeback(page, wbc, 1, count); xfs_start_page_writeback(page, 1, count);
if (ioend && iomap_valid) { if (ioend && iomap_valid) {
offset = (iomap.iomap_offset + iomap.iomap_bsize - 1) >> offset = (iomap.iomap_offset + iomap.iomap_bsize - 1) >>
......
...@@ -310,8 +310,7 @@ _xfs_buf_free_pages( ...@@ -310,8 +310,7 @@ _xfs_buf_free_pages(
xfs_buf_t *bp) xfs_buf_t *bp)
{ {
if (bp->b_pages != bp->b_page_array) { if (bp->b_pages != bp->b_page_array) {
kmem_free(bp->b_pages, kmem_free(bp->b_pages);
bp->b_page_count * sizeof(struct page *));
} }
} }
...@@ -1398,7 +1397,7 @@ STATIC void ...@@ -1398,7 +1397,7 @@ STATIC void
xfs_free_bufhash( xfs_free_bufhash(
xfs_buftarg_t *btp) xfs_buftarg_t *btp)
{ {
kmem_free(btp->bt_hash, (1<<btp->bt_hashshift) * sizeof(xfs_bufhash_t)); kmem_free(btp->bt_hash);
btp->bt_hash = NULL; btp->bt_hash = NULL;
} }
...@@ -1428,13 +1427,10 @@ xfs_unregister_buftarg( ...@@ -1428,13 +1427,10 @@ xfs_unregister_buftarg(
void void
xfs_free_buftarg( xfs_free_buftarg(
xfs_buftarg_t *btp, xfs_buftarg_t *btp)
int external)
{ {
xfs_flush_buftarg(btp, 1); xfs_flush_buftarg(btp, 1);
xfs_blkdev_issue_flush(btp); xfs_blkdev_issue_flush(btp);
if (external)
xfs_blkdev_put(btp->bt_bdev);
xfs_free_bufhash(btp); xfs_free_bufhash(btp);
iput(btp->bt_mapping->host); iput(btp->bt_mapping->host);
...@@ -1444,7 +1440,7 @@ xfs_free_buftarg( ...@@ -1444,7 +1440,7 @@ xfs_free_buftarg(
xfs_unregister_buftarg(btp); xfs_unregister_buftarg(btp);
kthread_stop(btp->bt_task); kthread_stop(btp->bt_task);
kmem_free(btp, sizeof(*btp)); kmem_free(btp);
} }
STATIC int STATIC int
...@@ -1575,7 +1571,7 @@ xfs_alloc_buftarg( ...@@ -1575,7 +1571,7 @@ xfs_alloc_buftarg(
return btp; return btp;
error: error:
kmem_free(btp, sizeof(*btp)); kmem_free(btp);
return NULL; return NULL;
} }
......
...@@ -429,7 +429,7 @@ static inline void xfs_bdwrite(void *mp, xfs_buf_t *bp) ...@@ -429,7 +429,7 @@ static inline void xfs_bdwrite(void *mp, xfs_buf_t *bp)
* Handling of buftargs. * Handling of buftargs.
*/ */
extern xfs_buftarg_t *xfs_alloc_buftarg(struct block_device *, int); extern xfs_buftarg_t *xfs_alloc_buftarg(struct block_device *, int);
extern void xfs_free_buftarg(xfs_buftarg_t *, int); extern void xfs_free_buftarg(xfs_buftarg_t *);
extern void xfs_wait_buftarg(xfs_buftarg_t *); extern void xfs_wait_buftarg(xfs_buftarg_t *);
extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int); extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int);
extern int xfs_flush_buftarg(xfs_buftarg_t *, int); extern int xfs_flush_buftarg(xfs_buftarg_t *, int);
......
...@@ -215,7 +215,7 @@ xfs_fs_get_parent( ...@@ -215,7 +215,7 @@ xfs_fs_get_parent(
struct xfs_inode *cip; struct xfs_inode *cip;
struct dentry *parent; struct dentry *parent;
error = xfs_lookup(XFS_I(child->d_inode), &xfs_name_dotdot, &cip); error = xfs_lookup(XFS_I(child->d_inode), &xfs_name_dotdot, &cip, NULL);
if (unlikely(error)) if (unlikely(error))
return ERR_PTR(-error); return ERR_PTR(-error);
......
This diff is collapsed.
This diff is collapsed.
...@@ -20,12 +20,14 @@ ...@@ -20,12 +20,14 @@
extern const struct inode_operations xfs_inode_operations; extern const struct inode_operations xfs_inode_operations;
extern const struct inode_operations xfs_dir_inode_operations; extern const struct inode_operations xfs_dir_inode_operations;
extern const struct inode_operations xfs_dir_ci_inode_operations;
extern const struct inode_operations xfs_symlink_inode_operations; extern const struct inode_operations xfs_symlink_inode_operations;
extern const struct file_operations xfs_file_operations; extern const struct file_operations xfs_file_operations;
extern const struct file_operations xfs_dir_file_operations; extern const struct file_operations xfs_dir_file_operations;
extern const struct file_operations xfs_invis_file_operations; extern const struct file_operations xfs_invis_file_operations;
extern ssize_t xfs_vn_listxattr(struct dentry *, char *data, size_t size);
struct xfs_inode; struct xfs_inode;
extern void xfs_ichgtime(struct xfs_inode *, int); extern void xfs_ichgtime(struct xfs_inode *, int);
......
...@@ -76,6 +76,7 @@ ...@@ -76,6 +76,7 @@
#include <linux/log2.h> #include <linux/log2.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/random.h> #include <linux/random.h>
#include <linux/ctype.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/div64.h> #include <asm/div64.h>
...@@ -299,4 +300,11 @@ static inline __uint64_t howmany_64(__uint64_t x, __uint32_t y) ...@@ -299,4 +300,11 @@ static inline __uint64_t howmany_64(__uint64_t x, __uint32_t y)
return x; return x;
} }
/* ARM old ABI has some weird alignment/padding */
#if defined(__arm__) && !defined(__ARM_EABI__)
#define __arch_pack __attribute__((packed))
#else
#define __arch_pack
#endif
#endif /* __XFS_LINUX__ */ #endif /* __XFS_LINUX__ */
...@@ -98,12 +98,21 @@ xfs_read_xfsstats( ...@@ -98,12 +98,21 @@ xfs_read_xfsstats(
return len; return len;
} }
void int
xfs_init_procfs(void) xfs_init_procfs(void)
{ {
if (!proc_mkdir("fs/xfs", NULL)) if (!proc_mkdir("fs/xfs", NULL))
return; goto out;
create_proc_read_entry("fs/xfs/stat", 0, NULL, xfs_read_xfsstats, NULL);
if (!create_proc_read_entry("fs/xfs/stat", 0, NULL,
xfs_read_xfsstats, NULL))
goto out_remove_entry;
return 0;
out_remove_entry:
remove_proc_entry("fs/xfs", NULL);
out:
return -ENOMEM;
} }
void void
......
...@@ -134,7 +134,7 @@ DECLARE_PER_CPU(struct xfsstats, xfsstats); ...@@ -134,7 +134,7 @@ DECLARE_PER_CPU(struct xfsstats, xfsstats);
#define XFS_STATS_DEC(v) (per_cpu(xfsstats, current_cpu()).v--) #define XFS_STATS_DEC(v) (per_cpu(xfsstats, current_cpu()).v--)
#define XFS_STATS_ADD(v, inc) (per_cpu(xfsstats, current_cpu()).v += (inc)) #define XFS_STATS_ADD(v, inc) (per_cpu(xfsstats, current_cpu()).v += (inc))
extern void xfs_init_procfs(void); extern int xfs_init_procfs(void);
extern void xfs_cleanup_procfs(void); extern void xfs_cleanup_procfs(void);
...@@ -144,8 +144,14 @@ extern void xfs_cleanup_procfs(void); ...@@ -144,8 +144,14 @@ extern void xfs_cleanup_procfs(void);
# define XFS_STATS_DEC(count) # define XFS_STATS_DEC(count)
# define XFS_STATS_ADD(count, inc) # define XFS_STATS_ADD(count, inc)
static inline void xfs_init_procfs(void) { }; static inline int xfs_init_procfs(void)
static inline void xfs_cleanup_procfs(void) { }; {
return 0;
}
static inline void xfs_cleanup_procfs(void)
{
}
#endif /* !CONFIG_PROC_FS */ #endif /* !CONFIG_PROC_FS */
......
This diff is collapsed.
...@@ -107,12 +107,10 @@ extern void xfs_initialize_vnode(struct xfs_mount *mp, bhv_vnode_t *vp, ...@@ -107,12 +107,10 @@ extern void xfs_initialize_vnode(struct xfs_mount *mp, bhv_vnode_t *vp,
extern void xfs_flush_inode(struct xfs_inode *); extern void xfs_flush_inode(struct xfs_inode *);
extern void xfs_flush_device(struct xfs_inode *); extern void xfs_flush_device(struct xfs_inode *);
extern int xfs_blkdev_get(struct xfs_mount *, const char *,
struct block_device **);
extern void xfs_blkdev_put(struct block_device *);
extern void xfs_blkdev_issue_flush(struct xfs_buftarg *); extern void xfs_blkdev_issue_flush(struct xfs_buftarg *);
extern const struct export_operations xfs_export_operations; extern const struct export_operations xfs_export_operations;
extern struct xattr_handler *xfs_xattr_handlers[];
#define XFS_M(sb) ((struct xfs_mount *)((sb)->s_fs_info)) #define XFS_M(sb) ((struct xfs_mount *)((sb)->s_fs_info))
......
...@@ -259,15 +259,17 @@ static ctl_table xfs_root_table[] = { ...@@ -259,15 +259,17 @@ static ctl_table xfs_root_table[] = {
{} {}
}; };
void int
xfs_sysctl_register(void) xfs_sysctl_register(void)
{ {
xfs_table_header = register_sysctl_table(xfs_root_table); xfs_table_header = register_sysctl_table(xfs_root_table);
if (!xfs_table_header)
return -ENOMEM;
return 0;
} }
void void
xfs_sysctl_unregister(void) xfs_sysctl_unregister(void)
{ {
if (xfs_table_header)
unregister_sysctl_table(xfs_table_header); unregister_sysctl_table(xfs_table_header);
} }
...@@ -93,10 +93,10 @@ enum { ...@@ -93,10 +93,10 @@ enum {
extern xfs_param_t xfs_params; extern xfs_param_t xfs_params;
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
extern void xfs_sysctl_register(void); extern int xfs_sysctl_register(void);
extern void xfs_sysctl_unregister(void); extern void xfs_sysctl_unregister(void);
#else #else
# define xfs_sysctl_register() do { } while (0) # define xfs_sysctl_register() (0)
# define xfs_sysctl_unregister() do { } while (0) # define xfs_sysctl_unregister() do { } while (0)
#endif /* CONFIG_SYSCTL */ #endif /* CONFIG_SYSCTL */
......
...@@ -82,56 +82,6 @@ vn_ioerror( ...@@ -82,56 +82,6 @@ vn_ioerror(
xfs_do_force_shutdown(ip->i_mount, SHUTDOWN_DEVICE_REQ, f, l); xfs_do_force_shutdown(ip->i_mount, SHUTDOWN_DEVICE_REQ, f, l);
} }
/*
* Revalidate the Linux inode from the XFS inode.
* Note: i_size _not_ updated; we must hold the inode
* semaphore when doing that - callers responsibility.
*/
int
vn_revalidate(
bhv_vnode_t *vp)
{
struct inode *inode = vn_to_inode(vp);
struct xfs_inode *ip = XFS_I(inode);
struct xfs_mount *mp = ip->i_mount;
unsigned long xflags;
xfs_itrace_entry(ip);
if (XFS_FORCED_SHUTDOWN(mp))
return -EIO;
xfs_ilock(ip, XFS_ILOCK_SHARED);
inode->i_mode = ip->i_d.di_mode;
inode->i_uid = ip->i_d.di_uid;
inode->i_gid = ip->i_d.di_gid;
inode->i_mtime.tv_sec = ip->i_d.di_mtime.t_sec;
inode->i_mtime.tv_nsec = ip->i_d.di_mtime.t_nsec;
inode->i_ctime.tv_sec = ip->i_d.di_ctime.t_sec;
inode->i_ctime.tv_nsec = ip->i_d.di_ctime.t_nsec;
xflags = xfs_ip2xflags(ip);
if (xflags & XFS_XFLAG_IMMUTABLE)
inode->i_flags |= S_IMMUTABLE;
else
inode->i_flags &= ~S_IMMUTABLE;
if (xflags & XFS_XFLAG_APPEND)
inode->i_flags |= S_APPEND;
else
inode->i_flags &= ~S_APPEND;
if (xflags & XFS_XFLAG_SYNC)
inode->i_flags |= S_SYNC;
else
inode->i_flags &= ~S_SYNC;
if (xflags & XFS_XFLAG_NOATIME)
inode->i_flags |= S_NOATIME;
else
inode->i_flags &= ~S_NOATIME;
xfs_iunlock(ip, XFS_ILOCK_SHARED);
xfs_iflags_clear(ip, XFS_IMODIFIED);
return 0;
}
/* /*
* Add a reference to a referenced vnode. * Add a reference to a referenced vnode.
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#define __XFS_VNODE_H__ #define __XFS_VNODE_H__
struct file; struct file;
struct bhv_vattr;
struct xfs_iomap; struct xfs_iomap;
struct attrlist_cursor_kern; struct attrlist_cursor_kern;
...@@ -66,87 +65,8 @@ static inline struct inode *vn_to_inode(bhv_vnode_t *vnode) ...@@ -66,87 +65,8 @@ static inline struct inode *vn_to_inode(bhv_vnode_t *vnode)
Prevent VM access to the pages until Prevent VM access to the pages until
the operation completes. */ the operation completes. */
/*
* Vnode attributes. va_mask indicates those attributes the caller
* wants to set or extract.
*/
typedef struct bhv_vattr {
int va_mask; /* bit-mask of attributes present */
mode_t va_mode; /* file access mode and type */
xfs_nlink_t va_nlink; /* number of references to file */
uid_t va_uid; /* owner user id */
gid_t va_gid; /* owner group id */
xfs_ino_t va_nodeid; /* file id */
xfs_off_t va_size; /* file size in bytes */
u_long va_blocksize; /* blocksize preferred for i/o */
struct timespec va_atime; /* time of last access */
struct timespec va_mtime; /* time of last modification */
struct timespec va_ctime; /* time file changed */
u_int va_gen; /* generation number of file */
xfs_dev_t va_rdev; /* device the special file represents */
__int64_t va_nblocks; /* number of blocks allocated */
u_long va_xflags; /* random extended file flags */
u_long va_extsize; /* file extent size */
u_long va_nextents; /* number of extents in file */
u_long va_anextents; /* number of attr extents in file */
prid_t va_projid; /* project id */
} bhv_vattr_t;
/*
* setattr or getattr attributes
*/
#define XFS_AT_TYPE 0x00000001
#define XFS_AT_MODE 0x00000002
#define XFS_AT_UID 0x00000004
#define XFS_AT_GID 0x00000008
#define XFS_AT_FSID 0x00000010
#define XFS_AT_NODEID 0x00000020
#define XFS_AT_NLINK 0x00000040
#define XFS_AT_SIZE 0x00000080
#define XFS_AT_ATIME 0x00000100
#define XFS_AT_MTIME 0x00000200
#define XFS_AT_CTIME 0x00000400
#define XFS_AT_RDEV 0x00000800
#define XFS_AT_BLKSIZE 0x00001000
#define XFS_AT_NBLOCKS 0x00002000
#define XFS_AT_VCODE 0x00004000
#define XFS_AT_MAC 0x00008000
#define XFS_AT_UPDATIME 0x00010000
#define XFS_AT_UPDMTIME 0x00020000
#define XFS_AT_UPDCTIME 0x00040000
#define XFS_AT_ACL 0x00080000
#define XFS_AT_CAP 0x00100000
#define XFS_AT_INF 0x00200000
#define XFS_AT_XFLAGS 0x00400000
#define XFS_AT_EXTSIZE 0x00800000
#define XFS_AT_NEXTENTS 0x01000000
#define XFS_AT_ANEXTENTS 0x02000000
#define XFS_AT_PROJID 0x04000000
#define XFS_AT_SIZE_NOPERM 0x08000000
#define XFS_AT_GENCOUNT 0x10000000
#define XFS_AT_ALL (XFS_AT_TYPE|XFS_AT_MODE|XFS_AT_UID|XFS_AT_GID|\
XFS_AT_FSID|XFS_AT_NODEID|XFS_AT_NLINK|XFS_AT_SIZE|\
XFS_AT_ATIME|XFS_AT_MTIME|XFS_AT_CTIME|XFS_AT_RDEV|\
XFS_AT_BLKSIZE|XFS_AT_NBLOCKS|XFS_AT_VCODE|XFS_AT_MAC|\
XFS_AT_ACL|XFS_AT_CAP|XFS_AT_INF|XFS_AT_XFLAGS|XFS_AT_EXTSIZE|\
XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|XFS_AT_PROJID|XFS_AT_GENCOUNT)
#define XFS_AT_STAT (XFS_AT_TYPE|XFS_AT_MODE|XFS_AT_UID|XFS_AT_GID|\
XFS_AT_FSID|XFS_AT_NODEID|XFS_AT_NLINK|XFS_AT_SIZE|\
XFS_AT_ATIME|XFS_AT_MTIME|XFS_AT_CTIME|XFS_AT_RDEV|\
XFS_AT_BLKSIZE|XFS_AT_NBLOCKS|XFS_AT_PROJID)
#define XFS_AT_TIMES (XFS_AT_ATIME|XFS_AT_MTIME|XFS_AT_CTIME)
#define XFS_AT_UPDTIMES (XFS_AT_UPDATIME|XFS_AT_UPDMTIME|XFS_AT_UPDCTIME)
#define XFS_AT_NOSET (XFS_AT_NLINK|XFS_AT_RDEV|XFS_AT_FSID|XFS_AT_NODEID|\
XFS_AT_TYPE|XFS_AT_BLKSIZE|XFS_AT_NBLOCKS|XFS_AT_VCODE|\
XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|XFS_AT_GENCOUNT)
extern void vn_init(void); extern void vn_init(void);
extern int vn_revalidate(bhv_vnode_t *);
/* /*
* Yeah, these don't take vnode anymore at all, all this should be * Yeah, these don't take vnode anymore at all, all this should be
...@@ -219,15 +139,6 @@ static inline void vn_atime_to_time_t(bhv_vnode_t *vp, time_t *tt) ...@@ -219,15 +139,6 @@ static inline void vn_atime_to_time_t(bhv_vnode_t *vp, time_t *tt)
#define VN_DIRTY(vp) mapping_tagged(vn_to_inode(vp)->i_mapping, \ #define VN_DIRTY(vp) mapping_tagged(vn_to_inode(vp)->i_mapping, \
PAGECACHE_TAG_DIRTY) PAGECACHE_TAG_DIRTY)
/*
* Flags to vop_setattr/getattr.
*/
#define ATTR_UTIME 0x01 /* non-default utime(2) request */
#define ATTR_DMI 0x08 /* invocation from a DMI function */
#define ATTR_LAZY 0x80 /* set/get attributes lazily */
#define ATTR_NONBLOCK 0x100 /* return EAGAIN if operation would block */
#define ATTR_NOLOCK 0x200 /* Don't grab any conflicting locks */
#define ATTR_NOSIZETOK 0x400 /* Don't get the SIZE token */
/* /*
* Tracking vnode activity. * Tracking vnode activity.
......
/*
* Copyright (C) 2008 Christoph Hellwig.
* Portions Copyright (C) 2000-2008 Silicon Graphics, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "xfs.h"
#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
#include "xfs_inode.h"
#include "xfs_attr.h"
#include "xfs_attr_leaf.h"
#include "xfs_acl.h"
#include "xfs_vnodeops.h"
#include <linux/posix_acl_xattr.h>
#include <linux/xattr.h>
/*
* ACL handling. Should eventually be moved into xfs_acl.c
*/
static int
xfs_decode_acl(const char *name)
{
if (strcmp(name, "posix_acl_access") == 0)
return _ACL_TYPE_ACCESS;
else if (strcmp(name, "posix_acl_default") == 0)
return _ACL_TYPE_DEFAULT;
return -EINVAL;
}
/*
* Get system extended attributes which at the moment only
* includes Posix ACLs.
*/
static int
xfs_xattr_system_get(struct inode *inode, const char *name,
void *buffer, size_t size)
{
int acl;
acl = xfs_decode_acl(name);
if (acl < 0)
return acl;
return xfs_acl_vget(inode, buffer, size, acl);
}
static int
xfs_xattr_system_set(struct inode *inode, const char *name,
const void *value, size_t size, int flags)
{
int acl;
acl = xfs_decode_acl(name);
if (acl < 0)
return acl;
if (flags & XATTR_CREATE)
return -EINVAL;
if (!value)
return xfs_acl_vremove(inode, acl);
return xfs_acl_vset(inode, (void *)value, size, acl);
}
static struct xattr_handler xfs_xattr_system_handler = {
.prefix = XATTR_SYSTEM_PREFIX,
.get = xfs_xattr_system_get,
.set = xfs_xattr_system_set,
};
/*
* Real xattr handling. The only difference between the namespaces is
* a flag passed to the low-level attr code.
*/
static int
__xfs_xattr_get(struct inode *inode, const char *name,
void *value, size_t size, int xflags)
{
struct xfs_inode *ip = XFS_I(inode);
int error, asize = size;
if (strcmp(name, "") == 0)
return -EINVAL;
/* Convert Linux syscall to XFS internal ATTR flags */
if (!size) {
xflags |= ATTR_KERNOVAL;
value = NULL;
}
error = -xfs_attr_get(ip, name, value, &asize, xflags);
if (error)
return error;
return asize;
}
static int
__xfs_xattr_set(struct inode *inode, const char *name, const void *value,
size_t size, int flags, int xflags)
{
struct xfs_inode *ip = XFS_I(inode);
if (strcmp(name, "") == 0)
return -EINVAL;
/* Convert Linux syscall to XFS internal ATTR flags */
if (flags & XATTR_CREATE)
xflags |= ATTR_CREATE;
if (flags & XATTR_REPLACE)
xflags |= ATTR_REPLACE;
if (!value)
return -xfs_attr_remove(ip, name, xflags);
return -xfs_attr_set(ip, name, (void *)value, size, xflags);
}
static int
xfs_xattr_user_get(struct inode *inode, const char *name,
void *value, size_t size)
{
return __xfs_xattr_get(inode, name, value, size, 0);
}
static int
xfs_xattr_user_set(struct inode *inode, const char *name,
const void *value, size_t size, int flags)
{
return __xfs_xattr_set(inode, name, value, size, flags, 0);
}
static struct xattr_handler xfs_xattr_user_handler = {
.prefix = XATTR_USER_PREFIX,
.get = xfs_xattr_user_get,
.set = xfs_xattr_user_set,
};
static int
xfs_xattr_trusted_get(struct inode *inode, const char *name,
void *value, size_t size)
{
return __xfs_xattr_get(inode, name, value, size, ATTR_ROOT);
}
static int
xfs_xattr_trusted_set(struct inode *inode, const char *name,
const void *value, size_t size, int flags)
{
return __xfs_xattr_set(inode, name, value, size, flags, ATTR_ROOT);
}
static struct xattr_handler xfs_xattr_trusted_handler = {
.prefix = XATTR_TRUSTED_PREFIX,
.get = xfs_xattr_trusted_get,
.set = xfs_xattr_trusted_set,
};
static int
xfs_xattr_secure_get(struct inode *inode, const char *name,
void *value, size_t size)
{
return __xfs_xattr_get(inode, name, value, size, ATTR_SECURE);
}
static int
xfs_xattr_secure_set(struct inode *inode, const char *name,
const void *value, size_t size, int flags)
{
return __xfs_xattr_set(inode, name, value, size, flags, ATTR_SECURE);
}
static struct xattr_handler xfs_xattr_security_handler = {
.prefix = XATTR_SECURITY_PREFIX,
.get = xfs_xattr_secure_get,
.set = xfs_xattr_secure_set,
};
struct xattr_handler *xfs_xattr_handlers[] = {
&xfs_xattr_user_handler,
&xfs_xattr_trusted_handler,
&xfs_xattr_security_handler,
&xfs_xattr_system_handler,
NULL
};
static unsigned int xfs_xattr_prefix_len(int flags)
{
if (flags & XFS_ATTR_SECURE)
return sizeof("security");
else if (flags & XFS_ATTR_ROOT)
return sizeof("trusted");
else
return sizeof("user");
}
static const char *xfs_xattr_prefix(int flags)
{
if (flags & XFS_ATTR_SECURE)
return xfs_xattr_security_handler.prefix;
else if (flags & XFS_ATTR_ROOT)
return xfs_xattr_trusted_handler.prefix;
else
return xfs_xattr_user_handler.prefix;
}
static int
xfs_xattr_put_listent(struct xfs_attr_list_context *context, int flags,
char *name, int namelen, int valuelen, char *value)
{
unsigned int prefix_len = xfs_xattr_prefix_len(flags);
char *offset;
int arraytop;
ASSERT(context->count >= 0);
/*
* Only show root namespace entries if we are actually allowed to
* see them.
*/
if ((flags & XFS_ATTR_ROOT) && !capable(CAP_SYS_ADMIN))
return 0;
arraytop = context->count + prefix_len + namelen + 1;
if (arraytop > context->firstu) {
context->count = -1; /* insufficient space */
return 1;
}
offset = (char *)context->alist + context->count;
strncpy(offset, xfs_xattr_prefix(flags), prefix_len);
offset += prefix_len;
strncpy(offset, name, namelen); /* real name */
offset += namelen;
*offset = '\0';
context->count += prefix_len + namelen + 1;
return 0;
}
static int
xfs_xattr_put_listent_sizes(struct xfs_attr_list_context *context, int flags,
char *name, int namelen, int valuelen, char *value)
{
context->count += xfs_xattr_prefix_len(flags) + namelen + 1;
return 0;
}
static int
list_one_attr(const char *name, const size_t len, void *data,
size_t size, ssize_t *result)
{
char *p = data + *result;
*result += len;
if (!size)
return 0;
if (*result > size)
return -ERANGE;
strcpy(p, name);
return 0;
}
ssize_t
xfs_vn_listxattr(struct dentry *dentry, char *data, size_t size)
{
struct xfs_attr_list_context context;
struct attrlist_cursor_kern cursor = { 0 };
struct inode *inode = dentry->d_inode;
int error;
/*
* First read the regular on-disk attributes.
*/
memset(&context, 0, sizeof(context));
context.dp = XFS_I(inode);
context.cursor = &cursor;
context.resynch = 1;
context.alist = data;
context.bufsize = size;
context.firstu = context.bufsize;
if (size)
context.put_listent = xfs_xattr_put_listent;
else
context.put_listent = xfs_xattr_put_listent_sizes;
xfs_attr_list_int(&context);
if (context.count < 0)
return -ERANGE;
/*
* Then add the two synthetic ACL attributes.
*/
if (xfs_acl_vhasacl_access(inode)) {
error = list_one_attr(POSIX_ACL_XATTR_ACCESS,
strlen(POSIX_ACL_XATTR_ACCESS) + 1,
data, size, &context.count);
if (error)
return error;
}
if (xfs_acl_vhasacl_default(inode)) {
error = list_one_attr(POSIX_ACL_XATTR_DEFAULT,
strlen(POSIX_ACL_XATTR_DEFAULT) + 1,
data, size, &context.count);
if (error)
return error;
}
return context.count;
}
...@@ -1435,8 +1435,7 @@ xfs_dqlock2( ...@@ -1435,8 +1435,7 @@ xfs_dqlock2(
/* ARGSUSED */ /* ARGSUSED */
int int
xfs_qm_dqpurge( xfs_qm_dqpurge(
xfs_dquot_t *dqp, xfs_dquot_t *dqp)
uint flags)
{ {
xfs_dqhash_t *thishash; xfs_dqhash_t *thishash;
xfs_mount_t *mp = dqp->q_mount; xfs_mount_t *mp = dqp->q_mount;
......
...@@ -164,7 +164,7 @@ extern void xfs_qm_dqprint(xfs_dquot_t *); ...@@ -164,7 +164,7 @@ extern void xfs_qm_dqprint(xfs_dquot_t *);
extern void xfs_qm_dqdestroy(xfs_dquot_t *); extern void xfs_qm_dqdestroy(xfs_dquot_t *);
extern int xfs_qm_dqflush(xfs_dquot_t *, uint); extern int xfs_qm_dqflush(xfs_dquot_t *, uint);
extern int xfs_qm_dqpurge(xfs_dquot_t *, uint); extern int xfs_qm_dqpurge(xfs_dquot_t *);
extern void xfs_qm_dqunpin_wait(xfs_dquot_t *); extern void xfs_qm_dqunpin_wait(xfs_dquot_t *);
extern int xfs_qm_dqlock_nowait(xfs_dquot_t *); extern int xfs_qm_dqlock_nowait(xfs_dquot_t *);
extern int xfs_qm_dqflock_nowait(xfs_dquot_t *); extern int xfs_qm_dqflock_nowait(xfs_dquot_t *);
......
...@@ -576,8 +576,8 @@ xfs_qm_qoffend_logitem_committed( ...@@ -576,8 +576,8 @@ xfs_qm_qoffend_logitem_committed(
* xfs_trans_delete_ail() drops the AIL lock. * xfs_trans_delete_ail() drops the AIL lock.
*/ */
xfs_trans_delete_ail(qfs->qql_item.li_mountp, (xfs_log_item_t *)qfs); xfs_trans_delete_ail(qfs->qql_item.li_mountp, (xfs_log_item_t *)qfs);
kmem_free(qfs, sizeof(xfs_qoff_logitem_t)); kmem_free(qfs);
kmem_free(qfe, sizeof(xfs_qoff_logitem_t)); kmem_free(qfe);
return (xfs_lsn_t)-1; return (xfs_lsn_t)-1;
} }
......
...@@ -192,8 +192,8 @@ xfs_qm_destroy( ...@@ -192,8 +192,8 @@ xfs_qm_destroy(
xfs_qm_list_destroy(&(xqm->qm_usr_dqhtable[i])); xfs_qm_list_destroy(&(xqm->qm_usr_dqhtable[i]));
xfs_qm_list_destroy(&(xqm->qm_grp_dqhtable[i])); xfs_qm_list_destroy(&(xqm->qm_grp_dqhtable[i]));
} }
kmem_free(xqm->qm_usr_dqhtable, hsize * sizeof(xfs_dqhash_t)); kmem_free(xqm->qm_usr_dqhtable);
kmem_free(xqm->qm_grp_dqhtable, hsize * sizeof(xfs_dqhash_t)); kmem_free(xqm->qm_grp_dqhtable);
xqm->qm_usr_dqhtable = NULL; xqm->qm_usr_dqhtable = NULL;
xqm->qm_grp_dqhtable = NULL; xqm->qm_grp_dqhtable = NULL;
xqm->qm_dqhashmask = 0; xqm->qm_dqhashmask = 0;
...@@ -201,7 +201,7 @@ xfs_qm_destroy( ...@@ -201,7 +201,7 @@ xfs_qm_destroy(
#ifdef DEBUG #ifdef DEBUG
mutex_destroy(&qcheck_lock); mutex_destroy(&qcheck_lock);
#endif #endif
kmem_free(xqm, sizeof(xfs_qm_t)); kmem_free(xqm);
} }
/* /*
...@@ -445,11 +445,11 @@ xfs_qm_unmount_quotas( ...@@ -445,11 +445,11 @@ xfs_qm_unmount_quotas(
} }
} }
if (uqp) { if (uqp) {
XFS_PURGE_INODE(uqp); IRELE(uqp);
mp->m_quotainfo->qi_uquotaip = NULL; mp->m_quotainfo->qi_uquotaip = NULL;
} }
if (gqp) { if (gqp) {
XFS_PURGE_INODE(gqp); IRELE(gqp);
mp->m_quotainfo->qi_gquotaip = NULL; mp->m_quotainfo->qi_gquotaip = NULL;
} }
out: out:
...@@ -631,7 +631,7 @@ xfs_qm_dqpurge_int( ...@@ -631,7 +631,7 @@ xfs_qm_dqpurge_int(
* freelist in INACTIVE state. * freelist in INACTIVE state.
*/ */
nextdqp = dqp->MPL_NEXT; nextdqp = dqp->MPL_NEXT;
nmisses += xfs_qm_dqpurge(dqp, flags); nmisses += xfs_qm_dqpurge(dqp);
dqp = nextdqp; dqp = nextdqp;
} }
xfs_qm_mplist_unlock(mp); xfs_qm_mplist_unlock(mp);
...@@ -1134,7 +1134,7 @@ xfs_qm_init_quotainfo( ...@@ -1134,7 +1134,7 @@ xfs_qm_init_quotainfo(
* and change the superblock accordingly. * and change the superblock accordingly.
*/ */
if ((error = xfs_qm_init_quotainos(mp))) { if ((error = xfs_qm_init_quotainos(mp))) {
kmem_free(qinf, sizeof(xfs_quotainfo_t)); kmem_free(qinf);
mp->m_quotainfo = NULL; mp->m_quotainfo = NULL;
return error; return error;
} }
...@@ -1240,15 +1240,15 @@ xfs_qm_destroy_quotainfo( ...@@ -1240,15 +1240,15 @@ xfs_qm_destroy_quotainfo(
xfs_qm_list_destroy(&qi->qi_dqlist); xfs_qm_list_destroy(&qi->qi_dqlist);
if (qi->qi_uquotaip) { if (qi->qi_uquotaip) {
XFS_PURGE_INODE(qi->qi_uquotaip); IRELE(qi->qi_uquotaip);
qi->qi_uquotaip = NULL; /* paranoia */ qi->qi_uquotaip = NULL; /* paranoia */
} }
if (qi->qi_gquotaip) { if (qi->qi_gquotaip) {
XFS_PURGE_INODE(qi->qi_gquotaip); IRELE(qi->qi_gquotaip);
qi->qi_gquotaip = NULL; qi->qi_gquotaip = NULL;
} }
mutex_destroy(&qi->qi_quotaofflock); mutex_destroy(&qi->qi_quotaofflock);
kmem_free(qi, sizeof(xfs_quotainfo_t)); kmem_free(qi);
mp->m_quotainfo = NULL; mp->m_quotainfo = NULL;
} }
...@@ -1394,7 +1394,7 @@ xfs_qm_qino_alloc( ...@@ -1394,7 +1394,7 @@ xfs_qm_qino_alloc(
* locked exclusively and joined to the transaction already. * locked exclusively and joined to the transaction already.
*/ */
ASSERT(xfs_isilocked(*ip, XFS_ILOCK_EXCL)); ASSERT(xfs_isilocked(*ip, XFS_ILOCK_EXCL));
VN_HOLD(XFS_ITOV((*ip))); IHOLD(*ip);
/* /*
* Make the changes in the superblock, and log those too. * Make the changes in the superblock, and log those too.
...@@ -1623,7 +1623,7 @@ xfs_qm_dqiterate( ...@@ -1623,7 +1623,7 @@ xfs_qm_dqiterate(
break; break;
} while (nmaps > 0); } while (nmaps > 0);
kmem_free(map, XFS_DQITER_MAP_SIZE * sizeof(*map)); kmem_free(map);
return error; return error;
} }
......
...@@ -362,11 +362,11 @@ xfs_qm_scall_quotaoff( ...@@ -362,11 +362,11 @@ xfs_qm_scall_quotaoff(
* if we don't need them anymore. * if we don't need them anymore.
*/ */
if ((dqtype & XFS_QMOPT_UQUOTA) && XFS_QI_UQIP(mp)) { if ((dqtype & XFS_QMOPT_UQUOTA) && XFS_QI_UQIP(mp)) {
XFS_PURGE_INODE(XFS_QI_UQIP(mp)); IRELE(XFS_QI_UQIP(mp));
XFS_QI_UQIP(mp) = NULL; XFS_QI_UQIP(mp) = NULL;
} }
if ((dqtype & (XFS_QMOPT_GQUOTA|XFS_QMOPT_PQUOTA)) && XFS_QI_GQIP(mp)) { if ((dqtype & (XFS_QMOPT_GQUOTA|XFS_QMOPT_PQUOTA)) && XFS_QI_GQIP(mp)) {
XFS_PURGE_INODE(XFS_QI_GQIP(mp)); IRELE(XFS_QI_GQIP(mp));
XFS_QI_GQIP(mp) = NULL; XFS_QI_GQIP(mp) = NULL;
} }
out_error: out_error:
...@@ -1449,14 +1449,14 @@ xfs_qm_internalqcheck( ...@@ -1449,14 +1449,14 @@ xfs_qm_internalqcheck(
for (d = (xfs_dqtest_t *) h1->qh_next; d != NULL; ) { for (d = (xfs_dqtest_t *) h1->qh_next; d != NULL; ) {
xfs_dqtest_cmp(d); xfs_dqtest_cmp(d);
e = (xfs_dqtest_t *) d->HL_NEXT; e = (xfs_dqtest_t *) d->HL_NEXT;
kmem_free(d, sizeof(xfs_dqtest_t)); kmem_free(d);
d = e; d = e;
} }
h1 = &qmtest_gdqtab[i]; h1 = &qmtest_gdqtab[i];
for (d = (xfs_dqtest_t *) h1->qh_next; d != NULL; ) { for (d = (xfs_dqtest_t *) h1->qh_next; d != NULL; ) {
xfs_dqtest_cmp(d); xfs_dqtest_cmp(d);
e = (xfs_dqtest_t *) d->HL_NEXT; e = (xfs_dqtest_t *) d->HL_NEXT;
kmem_free(d, sizeof(xfs_dqtest_t)); kmem_free(d);
d = e; d = e;
} }
} }
...@@ -1467,8 +1467,8 @@ xfs_qm_internalqcheck( ...@@ -1467,8 +1467,8 @@ xfs_qm_internalqcheck(
} else { } else {
cmn_err(CE_DEBUG, "******** quotacheck successful! ********"); cmn_err(CE_DEBUG, "******** quotacheck successful! ********");
} }
kmem_free(qmtest_udqtab, qmtest_hashmask * sizeof(xfs_dqhash_t)); kmem_free(qmtest_udqtab);
kmem_free(qmtest_gdqtab, qmtest_hashmask * sizeof(xfs_dqhash_t)); kmem_free(qmtest_gdqtab);
mutex_unlock(&qcheck_lock); mutex_unlock(&qcheck_lock);
return (qmtest_nfails); return (qmtest_nfails);
} }
......
...@@ -158,9 +158,6 @@ for ((dqp) = (qlist)->qh_next; (dqp) != (xfs_dquot_t *)(qlist); \ ...@@ -158,9 +158,6 @@ for ((dqp) = (qlist)->qh_next; (dqp) != (xfs_dquot_t *)(qlist); \
#define XFS_IS_SUSER_DQUOT(dqp) \ #define XFS_IS_SUSER_DQUOT(dqp) \
(!((dqp)->q_core.d_id)) (!((dqp)->q_core.d_id))
#define XFS_PURGE_INODE(ip) \
IRELE(ip);
#define DQFLAGTO_TYPESTR(d) (((d)->dq_flags & XFS_DQ_USER) ? "USR" : \ #define DQFLAGTO_TYPESTR(d) (((d)->dq_flags & XFS_DQ_USER) ? "USR" : \
(((d)->dq_flags & XFS_DQ_GROUP) ? "GRP" : \ (((d)->dq_flags & XFS_DQ_GROUP) ? "GRP" : \
(((d)->dq_flags & XFS_DQ_PROJ) ? "PRJ":"???"))) (((d)->dq_flags & XFS_DQ_PROJ) ? "PRJ":"???")))
......
...@@ -89,7 +89,7 @@ ktrace_alloc(int nentries, unsigned int __nocast sleep) ...@@ -89,7 +89,7 @@ ktrace_alloc(int nentries, unsigned int __nocast sleep)
if (sleep & KM_SLEEP) if (sleep & KM_SLEEP)
panic("ktrace_alloc: NULL memory on KM_SLEEP request!"); panic("ktrace_alloc: NULL memory on KM_SLEEP request!");
kmem_free(ktp, sizeof(*ktp)); kmem_free(ktp);
return NULL; return NULL;
} }
...@@ -126,7 +126,7 @@ ktrace_free(ktrace_t *ktp) ...@@ -126,7 +126,7 @@ ktrace_free(ktrace_t *ktp)
} else { } else {
entries_size = (int)(ktp->kt_nentries * sizeof(ktrace_entry_t)); entries_size = (int)(ktp->kt_nentries * sizeof(ktrace_entry_t));
kmem_free(ktp->kt_entries, entries_size); kmem_free(ktp->kt_entries);
} }
kmem_zone_free(ktrace_hdr_zone, ktp); kmem_zone_free(ktrace_hdr_zone, ktp);
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
*/ */
#include <xfs.h> #include <xfs.h>
static mutex_t uuid_monitor; static DEFINE_MUTEX(uuid_monitor);
static int uuid_table_size; static int uuid_table_size;
static uuid_t *uuid_table; static uuid_t *uuid_table;
...@@ -132,9 +132,3 @@ uuid_table_remove(uuid_t *uuid) ...@@ -132,9 +132,3 @@ uuid_table_remove(uuid_t *uuid)
ASSERT(i < uuid_table_size); ASSERT(i < uuid_table_size);
mutex_unlock(&uuid_monitor); mutex_unlock(&uuid_monitor);
} }
void __init
uuid_init(void)
{
mutex_init(&uuid_monitor);
}
...@@ -22,7 +22,6 @@ typedef struct { ...@@ -22,7 +22,6 @@ typedef struct {
unsigned char __u_bits[16]; unsigned char __u_bits[16];
} uuid_t; } uuid_t;
extern void uuid_init(void);
extern void uuid_create_nil(uuid_t *uuid); extern void uuid_create_nil(uuid_t *uuid);
extern int uuid_is_nil(uuid_t *uuid); extern int uuid_is_nil(uuid_t *uuid);
extern int uuid_equal(uuid_t *uuid1, uuid_t *uuid2); extern int uuid_equal(uuid_t *uuid1, uuid_t *uuid2);
......
...@@ -341,8 +341,7 @@ xfs_acl_iaccess( ...@@ -341,8 +341,7 @@ xfs_acl_iaccess(
/* If the file has no ACL return -1. */ /* If the file has no ACL return -1. */
rval = sizeof(xfs_acl_t); rval = sizeof(xfs_acl_t);
if (xfs_attr_fetch(ip, &acl_name, (char *)acl, &rval, if (xfs_attr_fetch(ip, &acl_name, (char *)acl, &rval, ATTR_ROOT)) {
ATTR_ROOT | ATTR_KERNACCESS)) {
_ACL_FREE(acl); _ACL_FREE(acl);
return -1; return -1;
} }
...@@ -720,7 +719,7 @@ xfs_acl_setmode( ...@@ -720,7 +719,7 @@ xfs_acl_setmode(
xfs_acl_t *acl, xfs_acl_t *acl,
int *basicperms) int *basicperms)
{ {
bhv_vattr_t va; struct iattr iattr;
xfs_acl_entry_t *ap; xfs_acl_entry_t *ap;
xfs_acl_entry_t *gap = NULL; xfs_acl_entry_t *gap = NULL;
int i, nomask = 1; int i, nomask = 1;
...@@ -734,25 +733,25 @@ xfs_acl_setmode( ...@@ -734,25 +733,25 @@ xfs_acl_setmode(
* Copy the u::, g::, o::, and m:: bits from the ACL into the * Copy the u::, g::, o::, and m:: bits from the ACL into the
* mode. The m:: bits take precedence over the g:: bits. * mode. The m:: bits take precedence over the g:: bits.
*/ */
va.va_mask = XFS_AT_MODE; iattr.ia_valid = ATTR_MODE;
va.va_mode = xfs_vtoi(vp)->i_d.di_mode; iattr.ia_mode = xfs_vtoi(vp)->i_d.di_mode;
va.va_mode &= ~(S_IRWXU|S_IRWXG|S_IRWXO); iattr.ia_mode &= ~(S_IRWXU|S_IRWXG|S_IRWXO);
ap = acl->acl_entry; ap = acl->acl_entry;
for (i = 0; i < acl->acl_cnt; ++i) { for (i = 0; i < acl->acl_cnt; ++i) {
switch (ap->ae_tag) { switch (ap->ae_tag) {
case ACL_USER_OBJ: case ACL_USER_OBJ:
va.va_mode |= ap->ae_perm << 6; iattr.ia_mode |= ap->ae_perm << 6;
break; break;
case ACL_GROUP_OBJ: case ACL_GROUP_OBJ:
gap = ap; gap = ap;
break; break;
case ACL_MASK: /* more than just standard modes */ case ACL_MASK: /* more than just standard modes */
nomask = 0; nomask = 0;
va.va_mode |= ap->ae_perm << 3; iattr.ia_mode |= ap->ae_perm << 3;
*basicperms = 0; *basicperms = 0;
break; break;
case ACL_OTHER: case ACL_OTHER:
va.va_mode |= ap->ae_perm; iattr.ia_mode |= ap->ae_perm;
break; break;
default: /* more than just standard modes */ default: /* more than just standard modes */
*basicperms = 0; *basicperms = 0;
...@@ -763,9 +762,9 @@ xfs_acl_setmode( ...@@ -763,9 +762,9 @@ xfs_acl_setmode(
/* Set the group bits from ACL_GROUP_OBJ if there's no ACL_MASK */ /* Set the group bits from ACL_GROUP_OBJ if there's no ACL_MASK */
if (gap && nomask) if (gap && nomask)
va.va_mode |= gap->ae_perm << 3; iattr.ia_mode |= gap->ae_perm << 3;
return xfs_setattr(xfs_vtoi(vp), &va, 0, sys_cred); return xfs_setattr(xfs_vtoi(vp), &iattr, 0, sys_cred);
} }
/* /*
......
...@@ -46,6 +46,8 @@ typedef struct xfs_acl { ...@@ -46,6 +46,8 @@ typedef struct xfs_acl {
#define SGI_ACL_FILE_SIZE (sizeof(SGI_ACL_FILE)-1) #define SGI_ACL_FILE_SIZE (sizeof(SGI_ACL_FILE)-1)
#define SGI_ACL_DEFAULT_SIZE (sizeof(SGI_ACL_DEFAULT)-1) #define SGI_ACL_DEFAULT_SIZE (sizeof(SGI_ACL_DEFAULT)-1)
#define _ACL_TYPE_ACCESS 1
#define _ACL_TYPE_DEFAULT 2
#ifdef CONFIG_XFS_POSIX_ACL #ifdef CONFIG_XFS_POSIX_ACL
...@@ -66,8 +68,6 @@ extern int xfs_acl_vset(bhv_vnode_t *, void *, size_t, int); ...@@ -66,8 +68,6 @@ extern int xfs_acl_vset(bhv_vnode_t *, void *, size_t, int);
extern int xfs_acl_vget(bhv_vnode_t *, void *, size_t, int); extern int xfs_acl_vget(bhv_vnode_t *, void *, size_t, int);
extern int xfs_acl_vremove(bhv_vnode_t *, int); extern int xfs_acl_vremove(bhv_vnode_t *, int);
#define _ACL_TYPE_ACCESS 1
#define _ACL_TYPE_DEFAULT 2
#define _ACL_PERM_INVALID(perm) ((perm) & ~(ACL_READ|ACL_WRITE|ACL_EXECUTE)) #define _ACL_PERM_INVALID(perm) ((perm) & ~(ACL_READ|ACL_WRITE|ACL_EXECUTE))
#define _ACL_INHERIT(c,m,d) (xfs_acl_inherit(c,m,d)) #define _ACL_INHERIT(c,m,d) (xfs_acl_inherit(c,m,d))
......
This diff is collapsed.
...@@ -18,9 +18,11 @@ ...@@ -18,9 +18,11 @@
#ifndef __XFS_ATTR_H__ #ifndef __XFS_ATTR_H__
#define __XFS_ATTR_H__ #define __XFS_ATTR_H__
struct xfs_inode;
struct xfs_da_args;
struct xfs_attr_list_context;
/* /*
* xfs_attr.h
*
* Large attribute lists are structured around Btrees where all the data * Large attribute lists are structured around Btrees where all the data
* elements are in the leaf nodes. Attribute names are hashed into an int, * elements are in the leaf nodes. Attribute names are hashed into an int,
* then that int is used as the index into the Btree. Since the hashval * then that int is used as the index into the Btree. Since the hashval
...@@ -35,35 +37,6 @@ ...@@ -35,35 +37,6 @@
* External interfaces * External interfaces
*========================================================================*/ *========================================================================*/
struct cred;
struct xfs_attr_list_context;
typedef int (*attrset_t)(bhv_vnode_t *, char *, void *, size_t, int);
typedef int (*attrget_t)(bhv_vnode_t *, char *, void *, size_t, int);
typedef int (*attrremove_t)(bhv_vnode_t *, char *, int);
typedef int (*attrexists_t)(bhv_vnode_t *);
typedef int (*attrcapable_t)(bhv_vnode_t *, struct cred *);
typedef struct attrnames {
char * attr_name;
unsigned int attr_namelen;
unsigned int attr_flag;
attrget_t attr_get;
attrset_t attr_set;
attrremove_t attr_remove;
attrexists_t attr_exists;
attrcapable_t attr_capable;
} attrnames_t;
#define ATTR_NAMECOUNT 4
extern struct attrnames attr_user;
extern struct attrnames attr_secure;
extern struct attrnames attr_system;
extern struct attrnames attr_trusted;
extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT];
extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int);
extern int attr_generic_list(bhv_vnode_t *, void *, size_t, int, ssize_t *);
#define ATTR_DONTFOLLOW 0x0001 /* -- unused, from IRIX -- */ #define ATTR_DONTFOLLOW 0x0001 /* -- unused, from IRIX -- */
#define ATTR_ROOT 0x0002 /* use attrs in root (trusted) namespace */ #define ATTR_ROOT 0x0002 /* use attrs in root (trusted) namespace */
...@@ -71,16 +44,9 @@ extern int attr_generic_list(bhv_vnode_t *, void *, size_t, int, ssize_t *); ...@@ -71,16 +44,9 @@ extern int attr_generic_list(bhv_vnode_t *, void *, size_t, int, ssize_t *);
#define ATTR_SECURE 0x0008 /* use attrs in security namespace */ #define ATTR_SECURE 0x0008 /* use attrs in security namespace */
#define ATTR_CREATE 0x0010 /* pure create: fail if attr already exists */ #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_REPLACE 0x0020 /* pure set: fail if attr does not exist */
#define ATTR_SYSTEM 0x0100 /* use attrs in system (pseudo) namespace */
#define ATTR_KERNACCESS 0x0400 /* [kernel] iaccess, inode held io-locked */
#define ATTR_KERNOTIME 0x1000 /* [kernel] don't update inode timestamps */ #define ATTR_KERNOTIME 0x1000 /* [kernel] don't update inode timestamps */
#define ATTR_KERNOVAL 0x2000 /* [kernel] get attr size only, not value */ #define ATTR_KERNOVAL 0x2000 /* [kernel] get attr size only, not value */
#define ATTR_KERNAMELS 0x4000 /* [kernel] list attr names (simple list) */
#define ATTR_KERNORMALS 0x0800 /* [kernel] normal attr list: user+secure */
#define ATTR_KERNROOTLS 0x8000 /* [kernel] include root in the attr list */
#define ATTR_KERNFULLS (ATTR_KERNORMALS|ATTR_KERNROOTLS)
/* /*
* The maximum size (into the kernel or returned from the kernel) of an * The maximum size (into the kernel or returned from the kernel) of an
...@@ -118,22 +84,6 @@ typedef struct attrlist_ent { /* data from attr_list() */ ...@@ -118,22 +84,6 @@ typedef struct attrlist_ent { /* data from attr_list() */
((attrlist_ent_t *) \ ((attrlist_ent_t *) \
&((char *)buffer)[ ((attrlist_t *)(buffer))->al_offset[index] ]) &((char *)buffer)[ ((attrlist_t *)(buffer))->al_offset[index] ])
/*
* Multi-attribute operation vector.
*/
typedef struct attr_multiop {
int am_opcode; /* operation to perform (ATTR_OP_GET, etc.) */
int am_error; /* [out arg] result of this sub-op (an errno) */
char *am_attrname; /* attribute name to work with */
char *am_attrvalue; /* [in/out arg] attribute value (raw bytes) */
int am_length; /* [in/out arg] length of value */
int am_flags; /* bitwise OR of attr API flags defined above */
} attr_multiop_t;
#define ATTR_OP_GET 1 /* return the indicated attr's value */
#define ATTR_OP_SET 2 /* set/create the indicated attr/value pair */
#define ATTR_OP_REMOVE 3 /* remove the indicated attr */
/* /*
* Kernel-internal version of the attrlist cursor. * Kernel-internal version of the attrlist cursor.
*/ */
...@@ -148,20 +98,40 @@ typedef struct attrlist_cursor_kern { ...@@ -148,20 +98,40 @@ typedef struct attrlist_cursor_kern {
/*======================================================================== /*========================================================================
* Function prototypes for the kernel. * Structure used to pass context around among the routines.
*========================================================================*/ *========================================================================*/
struct xfs_inode;
struct attrlist_cursor_kern; typedef int (*put_listent_func_t)(struct xfs_attr_list_context *, int,
struct xfs_da_args; char *, int, int, char *);
typedef struct xfs_attr_list_context {
struct xfs_inode *dp; /* inode */
struct attrlist_cursor_kern *cursor; /* position in list */
char *alist; /* output buffer */
int seen_enough; /* T/F: seen enough of list? */
ssize_t count; /* num used entries */
int dupcnt; /* count dup hashvals seen */
int bufsize; /* total buffer size */
int firstu; /* first used byte in buffer */
int flags; /* from VOP call */
int resynch; /* T/F: resynch with cursor */
int put_value; /* T/F: need value for listent */
put_listent_func_t put_listent; /* list output fmt function */
int index; /* index into output buffer */
} xfs_attr_list_context_t;
/*========================================================================
* Function prototypes for the kernel.
*========================================================================*/
/* /*
* Overall external interface routines. * Overall external interface routines.
*/ */
int xfs_attr_inactive(struct xfs_inode *dp); int xfs_attr_inactive(struct xfs_inode *dp);
int xfs_attr_shortform_getvalue(struct xfs_da_args *);
int xfs_attr_fetch(struct xfs_inode *, struct xfs_name *, char *, int *, int); int xfs_attr_fetch(struct xfs_inode *, struct xfs_name *, char *, int *, int);
int xfs_attr_rmtval_get(struct xfs_da_args *args); int xfs_attr_rmtval_get(struct xfs_da_args *args);
int xfs_attr_list_int(struct xfs_attr_list_context *);
#endif /* __XFS_ATTR_H__ */ #endif /* __XFS_ATTR_H__ */
...@@ -94,13 +94,6 @@ STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index); ...@@ -94,13 +94,6 @@ STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index);
* Namespace helper routines * Namespace helper routines
*========================================================================*/ *========================================================================*/
STATIC_INLINE attrnames_t *
xfs_attr_flags_namesp(int flags)
{
return ((flags & XFS_ATTR_SECURE) ? &attr_secure:
((flags & XFS_ATTR_ROOT) ? &attr_trusted : &attr_user));
}
/* /*
* If namespace bits don't match return 0. * If namespace bits don't match return 0.
* If all match then return 1. * If all match then return 1.
...@@ -111,25 +104,6 @@ xfs_attr_namesp_match(int arg_flags, int ondisk_flags) ...@@ -111,25 +104,6 @@ xfs_attr_namesp_match(int arg_flags, int ondisk_flags)
return XFS_ATTR_NSP_ONDISK(ondisk_flags) == XFS_ATTR_NSP_ARGS_TO_ONDISK(arg_flags); return XFS_ATTR_NSP_ONDISK(ondisk_flags) == XFS_ATTR_NSP_ARGS_TO_ONDISK(arg_flags);
} }
/*
* If namespace bits don't match and we don't have an override for it
* then return 0.
* If all match or are overridable then return 1.
*/
STATIC_INLINE int
xfs_attr_namesp_match_overrides(int arg_flags, int ondisk_flags)
{
if (((arg_flags & ATTR_SECURE) == 0) !=
((ondisk_flags & XFS_ATTR_SECURE) == 0) &&
!(arg_flags & ATTR_KERNORMALS))
return 0;
if (((arg_flags & ATTR_ROOT) == 0) !=
((ondisk_flags & XFS_ATTR_ROOT) == 0) &&
!(arg_flags & ATTR_KERNROOTLS))
return 0;
return 1;
}
/*======================================================================== /*========================================================================
* External routines when attribute fork size < XFS_LITINO(mp). * External routines when attribute fork size < XFS_LITINO(mp).
...@@ -369,7 +343,8 @@ xfs_attr_shortform_remove(xfs_da_args_t *args) ...@@ -369,7 +343,8 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
* Fix up the start offset of the attribute fork * Fix up the start offset of the attribute fork
*/ */
totsize -= size; totsize -= size;
if (totsize == sizeof(xfs_attr_sf_hdr_t) && !args->addname && if (totsize == sizeof(xfs_attr_sf_hdr_t) &&
!(args->op_flags & XFS_DA_OP_ADDNAME) &&
(mp->m_flags & XFS_MOUNT_ATTR2) && (mp->m_flags & XFS_MOUNT_ATTR2) &&
(dp->i_d.di_format != XFS_DINODE_FMT_BTREE)) { (dp->i_d.di_format != XFS_DINODE_FMT_BTREE)) {
/* /*
...@@ -389,7 +364,8 @@ xfs_attr_shortform_remove(xfs_da_args_t *args) ...@@ -389,7 +364,8 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
xfs_idata_realloc(dp, -size, XFS_ATTR_FORK); xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
dp->i_d.di_forkoff = xfs_attr_shortform_bytesfit(dp, totsize); dp->i_d.di_forkoff = xfs_attr_shortform_bytesfit(dp, totsize);
ASSERT(dp->i_d.di_forkoff); ASSERT(dp->i_d.di_forkoff);
ASSERT(totsize > sizeof(xfs_attr_sf_hdr_t) || args->addname || ASSERT(totsize > sizeof(xfs_attr_sf_hdr_t) ||
(args->op_flags & XFS_DA_OP_ADDNAME) ||
!(mp->m_flags & XFS_MOUNT_ATTR2) || !(mp->m_flags & XFS_MOUNT_ATTR2) ||
dp->i_d.di_format == XFS_DINODE_FMT_BTREE); dp->i_d.di_format == XFS_DINODE_FMT_BTREE);
dp->i_afp->if_ext_max = dp->i_afp->if_ext_max =
...@@ -531,7 +507,7 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args) ...@@ -531,7 +507,7 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args)
nargs.total = args->total; nargs.total = args->total;
nargs.whichfork = XFS_ATTR_FORK; nargs.whichfork = XFS_ATTR_FORK;
nargs.trans = args->trans; nargs.trans = args->trans;
nargs.oknoent = 1; nargs.op_flags = XFS_DA_OP_OKNOENT;
sfe = &sf->list[0]; sfe = &sf->list[0];
for (i = 0; i < sf->hdr.count; i++) { for (i = 0; i < sf->hdr.count; i++) {
...@@ -555,7 +531,7 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args) ...@@ -555,7 +531,7 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args)
out: out:
if(bp) if(bp)
xfs_da_buf_done(bp); xfs_da_buf_done(bp);
kmem_free(tmpbuffer, size); kmem_free(tmpbuffer);
return(error); return(error);
} }
...@@ -624,15 +600,8 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) ...@@ -624,15 +600,8 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
(XFS_ISRESET_CURSOR(cursor) && (XFS_ISRESET_CURSOR(cursor) &&
(dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize)) { (dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize)) {
for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) { for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) {
attrnames_t *namesp;
if (!xfs_attr_namesp_match_overrides(context->flags, sfe->flags)) {
sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
continue;
}
namesp = xfs_attr_flags_namesp(sfe->flags);
error = context->put_listent(context, error = context->put_listent(context,
namesp, sfe->flags,
(char *)sfe->nameval, (char *)sfe->nameval,
(int)sfe->namelen, (int)sfe->namelen,
(int)sfe->valuelen, (int)sfe->valuelen,
...@@ -676,13 +645,10 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) ...@@ -676,13 +645,10 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
XFS_ERRLEVEL_LOW, XFS_ERRLEVEL_LOW,
context->dp->i_mount, sfe); context->dp->i_mount, sfe);
xfs_attr_trace_l_c("sf corrupted", context); xfs_attr_trace_l_c("sf corrupted", context);
kmem_free(sbuf, sbsize); kmem_free(sbuf);
return XFS_ERROR(EFSCORRUPTED); return XFS_ERROR(EFSCORRUPTED);
} }
if (!xfs_attr_namesp_match_overrides(context->flags, sfe->flags)) {
sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
continue;
}
sbp->entno = i; sbp->entno = i;
sbp->hash = xfs_da_hashname((char *)sfe->nameval, sfe->namelen); sbp->hash = xfs_da_hashname((char *)sfe->nameval, sfe->namelen);
sbp->name = (char *)sfe->nameval; sbp->name = (char *)sfe->nameval;
...@@ -717,7 +683,7 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) ...@@ -717,7 +683,7 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
} }
} }
if (i == nsbuf) { if (i == nsbuf) {
kmem_free(sbuf, sbsize); kmem_free(sbuf);
xfs_attr_trace_l_c("blk end", context); xfs_attr_trace_l_c("blk end", context);
return(0); return(0);
} }
...@@ -726,16 +692,12 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) ...@@ -726,16 +692,12 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
* Loop putting entries into the user buffer. * Loop putting entries into the user buffer.
*/ */
for ( ; i < nsbuf; i++, sbp++) { for ( ; i < nsbuf; i++, sbp++) {
attrnames_t *namesp;
namesp = xfs_attr_flags_namesp(sbp->flags);
if (cursor->hashval != sbp->hash) { if (cursor->hashval != sbp->hash) {
cursor->hashval = sbp->hash; cursor->hashval = sbp->hash;
cursor->offset = 0; cursor->offset = 0;
} }
error = context->put_listent(context, error = context->put_listent(context,
namesp, sbp->flags,
sbp->name, sbp->name,
sbp->namelen, sbp->namelen,
sbp->valuelen, sbp->valuelen,
...@@ -747,7 +709,7 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) ...@@ -747,7 +709,7 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
cursor->offset++; cursor->offset++;
} }
kmem_free(sbuf, sbsize); kmem_free(sbuf);
xfs_attr_trace_l_c("sf E-O-F", context); xfs_attr_trace_l_c("sf E-O-F", context);
return(0); return(0);
} }
...@@ -853,7 +815,7 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff) ...@@ -853,7 +815,7 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff)
nargs.total = args->total; nargs.total = args->total;
nargs.whichfork = XFS_ATTR_FORK; nargs.whichfork = XFS_ATTR_FORK;
nargs.trans = args->trans; nargs.trans = args->trans;
nargs.oknoent = 1; nargs.op_flags = XFS_DA_OP_OKNOENT;
entry = &leaf->entries[0]; entry = &leaf->entries[0];
for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) { for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) {
if (entry->flags & XFS_ATTR_INCOMPLETE) if (entry->flags & XFS_ATTR_INCOMPLETE)
...@@ -873,7 +835,7 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff) ...@@ -873,7 +835,7 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff)
error = 0; error = 0;
out: out:
kmem_free(tmpbuffer, XFS_LBSIZE(dp->i_mount)); kmem_free(tmpbuffer);
return(error); return(error);
} }
...@@ -1155,7 +1117,7 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex) ...@@ -1155,7 +1117,7 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex)
entry->hashval = cpu_to_be32(args->hashval); entry->hashval = cpu_to_be32(args->hashval);
entry->flags = tmp ? XFS_ATTR_LOCAL : 0; entry->flags = tmp ? XFS_ATTR_LOCAL : 0;
entry->flags |= XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags); entry->flags |= XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags);
if (args->rename) { if (args->op_flags & XFS_DA_OP_RENAME) {
entry->flags |= XFS_ATTR_INCOMPLETE; entry->flags |= XFS_ATTR_INCOMPLETE;
if ((args->blkno2 == args->blkno) && if ((args->blkno2 == args->blkno) &&
(args->index2 <= args->index)) { (args->index2 <= args->index)) {
...@@ -1271,7 +1233,7 @@ xfs_attr_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *bp) ...@@ -1271,7 +1233,7 @@ xfs_attr_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *bp)
be16_to_cpu(hdr_s->count), mp); be16_to_cpu(hdr_s->count), mp);
xfs_da_log_buf(trans, bp, 0, XFS_LBSIZE(mp) - 1); xfs_da_log_buf(trans, bp, 0, XFS_LBSIZE(mp) - 1);
kmem_free(tmpbuffer, XFS_LBSIZE(mp)); kmem_free(tmpbuffer);
} }
/* /*
...@@ -1921,7 +1883,7 @@ xfs_attr_leaf_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, ...@@ -1921,7 +1883,7 @@ xfs_attr_leaf_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,
be16_to_cpu(drop_hdr->count), mp); be16_to_cpu(drop_hdr->count), mp);
} }
memcpy((char *)save_leaf, (char *)tmp_leaf, state->blocksize); memcpy((char *)save_leaf, (char *)tmp_leaf, state->blocksize);
kmem_free(tmpbuffer, state->blocksize); kmem_free(tmpbuffer);
} }
xfs_da_log_buf(state->args->trans, save_blk->bp, 0, xfs_da_log_buf(state->args->trans, save_blk->bp, 0,
...@@ -2400,8 +2362,6 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context) ...@@ -2400,8 +2362,6 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context)
*/ */
retval = 0; retval = 0;
for ( ; (i < be16_to_cpu(leaf->hdr.count)); entry++, i++) { for ( ; (i < be16_to_cpu(leaf->hdr.count)); entry++, i++) {
attrnames_t *namesp;
if (be32_to_cpu(entry->hashval) != cursor->hashval) { if (be32_to_cpu(entry->hashval) != cursor->hashval) {
cursor->hashval = be32_to_cpu(entry->hashval); cursor->hashval = be32_to_cpu(entry->hashval);
cursor->offset = 0; cursor->offset = 0;
...@@ -2409,17 +2369,13 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context) ...@@ -2409,17 +2369,13 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context)
if (entry->flags & XFS_ATTR_INCOMPLETE) if (entry->flags & XFS_ATTR_INCOMPLETE)
continue; /* skip incomplete entries */ continue; /* skip incomplete entries */
if (!xfs_attr_namesp_match_overrides(context->flags, entry->flags))
continue;
namesp = xfs_attr_flags_namesp(entry->flags);
if (entry->flags & XFS_ATTR_LOCAL) { if (entry->flags & XFS_ATTR_LOCAL) {
xfs_attr_leaf_name_local_t *name_loc = xfs_attr_leaf_name_local_t *name_loc =
XFS_ATTR_LEAF_NAME_LOCAL(leaf, i); XFS_ATTR_LEAF_NAME_LOCAL(leaf, i);
retval = context->put_listent(context, retval = context->put_listent(context,
namesp, entry->flags,
(char *)name_loc->nameval, (char *)name_loc->nameval,
(int)name_loc->namelen, (int)name_loc->namelen,
be16_to_cpu(name_loc->valuelen), be16_to_cpu(name_loc->valuelen),
...@@ -2446,16 +2402,15 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context) ...@@ -2446,16 +2402,15 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context)
if (retval) if (retval)
return retval; return retval;
retval = context->put_listent(context, retval = context->put_listent(context,
namesp, entry->flags,
(char *)name_rmt->name, (char *)name_rmt->name,
(int)name_rmt->namelen, (int)name_rmt->namelen,
valuelen, valuelen,
(char*)args.value); (char*)args.value);
kmem_free(args.value, valuelen); kmem_free(args.value);
} } else {
else {
retval = context->put_listent(context, retval = context->put_listent(context,
namesp, entry->flags,
(char *)name_rmt->name, (char *)name_rmt->name,
(int)name_rmt->namelen, (int)name_rmt->namelen,
valuelen, valuelen,
...@@ -2954,7 +2909,7 @@ xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp) ...@@ -2954,7 +2909,7 @@ xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp)
error = tmp; /* save only the 1st errno */ error = tmp; /* save only the 1st errno */
} }
kmem_free((xfs_caddr_t)list, size); kmem_free((xfs_caddr_t)list);
return(error); return(error);
} }
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
struct attrlist; struct attrlist;
struct attrlist_cursor_kern; struct attrlist_cursor_kern;
struct attrnames; struct xfs_attr_list_context;
struct xfs_dabuf; struct xfs_dabuf;
struct xfs_da_args; struct xfs_da_args;
struct xfs_da_state; struct xfs_da_state;
...@@ -204,33 +204,6 @@ static inline int xfs_attr_leaf_entsize_local_max(int bsize) ...@@ -204,33 +204,6 @@ static inline int xfs_attr_leaf_entsize_local_max(int bsize)
return (((bsize) >> 1) + ((bsize) >> 2)); return (((bsize) >> 1) + ((bsize) >> 2));
} }
/*========================================================================
* Structure used to pass context around among the routines.
*========================================================================*/
struct xfs_attr_list_context;
typedef int (*put_listent_func_t)(struct xfs_attr_list_context *, struct attrnames *,
char *, int, int, char *);
typedef struct xfs_attr_list_context {
struct xfs_inode *dp; /* inode */
struct attrlist_cursor_kern *cursor; /* position in list */
struct attrlist *alist; /* output buffer */
int seen_enough; /* T/F: seen enough of list? */
int count; /* num used entries */
int dupcnt; /* count dup hashvals seen */
int bufsize; /* total buffer size */
int firstu; /* first used byte in buffer */
int flags; /* from VOP call */
int resynch; /* T/F: resynch with cursor */
int put_value; /* T/F: need value for listent */
put_listent_func_t put_listent; /* list output fmt function */
int index; /* index into output buffer */
} xfs_attr_list_context_t;
/* /*
* Used to keep a list of "remote value" extents when unlinking an inode. * Used to keep a list of "remote value" extents when unlinking an inode.
*/ */
......
...@@ -97,13 +97,9 @@ void xfs_attr_trace_l_cb(char *where, struct xfs_attr_list_context *context, ...@@ -97,13 +97,9 @@ void xfs_attr_trace_l_cb(char *where, struct xfs_attr_list_context *context,
void xfs_attr_trace_l_cl(char *where, struct xfs_attr_list_context *context, void xfs_attr_trace_l_cl(char *where, struct xfs_attr_list_context *context,
struct xfs_attr_leafblock *leaf); struct xfs_attr_leafblock *leaf);
void xfs_attr_trace_enter(int type, char *where, void xfs_attr_trace_enter(int type, char *where,
__psunsigned_t a2, __psunsigned_t a3, struct xfs_attr_list_context *context,
__psunsigned_t a4, __psunsigned_t a5, __psunsigned_t a13, __psunsigned_t a14,
__psunsigned_t a6, __psunsigned_t a7, __psunsigned_t a15);
__psunsigned_t a8, __psunsigned_t a9,
__psunsigned_t a10, __psunsigned_t a11,
__psunsigned_t a12, __psunsigned_t a13,
__psunsigned_t a14, __psunsigned_t a15);
#else #else
#define xfs_attr_trace_l_c(w,c) #define xfs_attr_trace_l_c(w,c)
#define xfs_attr_trace_l_cn(w,c,n) #define xfs_attr_trace_l_cn(w,c,n)
......
This diff is collapsed.
...@@ -54,12 +54,23 @@ typedef struct xfs_bmap_free_item ...@@ -54,12 +54,23 @@ typedef struct xfs_bmap_free_item
/* /*
* Header for free extent list. * Header for free extent list.
*
* xbf_low is used by the allocator to activate the lowspace algorithm -
* when free space is running low the extent allocator may choose to
* allocate an extent from an AG without leaving sufficient space for
* a btree split when inserting the new extent. In this case the allocator
* will enable the lowspace algorithm which is supposed to allow further
* allocations (such as btree splits and newroots) to allocate from
* sequential AGs. In order to avoid locking AGs out of order the lowspace
* algorithm will start searching for free space from AG 0. If the correct
* transaction reservations have been made then this algorithm will eventually
* find all the space it needs.
*/ */
typedef struct xfs_bmap_free typedef struct xfs_bmap_free
{ {
xfs_bmap_free_item_t *xbf_first; /* list of to-be-free extents */ xfs_bmap_free_item_t *xbf_first; /* list of to-be-free extents */
int xbf_count; /* count of items on list */ int xbf_count; /* count of items on list */
int xbf_low; /* kludge: alloc in low mode */ int xbf_low; /* alloc in low mode */
} xfs_bmap_free_t; } xfs_bmap_free_t;
#define XFS_BMAP_MAX_NMAP 4 #define XFS_BMAP_MAX_NMAP 4
......
...@@ -1493,12 +1493,27 @@ xfs_bmbt_split( ...@@ -1493,12 +1493,27 @@ xfs_bmbt_split(
left = XFS_BUF_TO_BMBT_BLOCK(lbp); left = XFS_BUF_TO_BMBT_BLOCK(lbp);
args.fsbno = cur->bc_private.b.firstblock; args.fsbno = cur->bc_private.b.firstblock;
args.firstblock = args.fsbno; args.firstblock = args.fsbno;
args.minleft = 0;
if (args.fsbno == NULLFSBLOCK) { if (args.fsbno == NULLFSBLOCK) {
args.fsbno = lbno; args.fsbno = lbno;
args.type = XFS_ALLOCTYPE_START_BNO; args.type = XFS_ALLOCTYPE_START_BNO;
} else /*
* Make sure there is sufficient room left in the AG to
* complete a full tree split for an extent insert. If
* we are converting the middle part of an extent then
* we may need space for two tree splits.
*
* We are relying on the caller to make the correct block
* reservation for this operation to succeed. If the
* reservation amount is insufficient then we may fail a
* block allocation here and corrupt the filesystem.
*/
args.minleft = xfs_trans_get_block_res(args.tp);
} else if (cur->bc_private.b.flist->xbf_low)
args.type = XFS_ALLOCTYPE_START_BNO;
else
args.type = XFS_ALLOCTYPE_NEAR_BNO; args.type = XFS_ALLOCTYPE_NEAR_BNO;
args.mod = args.minleft = args.alignment = args.total = args.isfl = args.mod = args.alignment = args.total = args.isfl =
args.userdata = args.minalignslop = 0; args.userdata = args.minalignslop = 0;
args.minlen = args.maxlen = args.prod = 1; args.minlen = args.maxlen = args.prod = 1;
args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL; args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL;
...@@ -1510,6 +1525,21 @@ xfs_bmbt_split( ...@@ -1510,6 +1525,21 @@ xfs_bmbt_split(
XFS_BMBT_TRACE_CURSOR(cur, ERROR); XFS_BMBT_TRACE_CURSOR(cur, ERROR);
return error; return error;
} }
if (args.fsbno == NULLFSBLOCK && args.minleft) {
/*
* Could not find an AG with enough free space to satisfy
* a full btree split. Try again without minleft and if
* successful activate the lowspace algorithm.
*/
args.fsbno = 0;
args.type = XFS_ALLOCTYPE_FIRST_AG;
args.minleft = 0;
if ((error = xfs_alloc_vextent(&args))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
return error;
}
cur->bc_private.b.flist->xbf_low = 1;
}
if (args.fsbno == NULLFSBLOCK) { if (args.fsbno == NULLFSBLOCK) {
XFS_BMBT_TRACE_CURSOR(cur, EXIT); XFS_BMBT_TRACE_CURSOR(cur, EXIT);
*stat = 0; *stat = 0;
...@@ -2029,22 +2059,8 @@ xfs_bmbt_increment( ...@@ -2029,22 +2059,8 @@ xfs_bmbt_increment(
* Insert the current record at the point referenced by cur. * Insert the current record at the point referenced by cur.
* *
* A multi-level split of the tree on insert will invalidate the original * A multi-level split of the tree on insert will invalidate the original
* cursor. It appears, however, that some callers assume that the cursor is * cursor. All callers of this function should assume that the cursor is
* always valid. Hence if we do a multi-level split we need to revalidate the * no longer valid and revalidate it.
* cursor.
*
* When a split occurs, we will see a new cursor returned. Use that as a
* trigger to determine if we need to revalidate the original cursor. If we get
* a split, then use the original irec to lookup up the path of the record we
* just inserted.
*
* Note that the fact that the btree root is in the inode means that we can
* have the level of the tree change without a "split" occurring at the root
* level. What happens is that the root is migrated to an allocated block and
* the inode root is pointed to it. This means a single split can change the
* level of the tree (level 2 -> level 3) and invalidate the old cursor. Hence
* the level change should be accounted as a split so as to correctly trigger a
* revalidation of the old cursor.
*/ */
int /* error */ int /* error */
xfs_bmbt_insert( xfs_bmbt_insert(
...@@ -2057,14 +2073,11 @@ xfs_bmbt_insert( ...@@ -2057,14 +2073,11 @@ xfs_bmbt_insert(
xfs_fsblock_t nbno; xfs_fsblock_t nbno;
xfs_btree_cur_t *ncur; xfs_btree_cur_t *ncur;
xfs_bmbt_rec_t nrec; xfs_bmbt_rec_t nrec;
xfs_bmbt_irec_t oirec; /* original irec */
xfs_btree_cur_t *pcur; xfs_btree_cur_t *pcur;
int splits = 0;
XFS_BMBT_TRACE_CURSOR(cur, ENTRY); XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
level = 0; level = 0;
nbno = NULLFSBLOCK; nbno = NULLFSBLOCK;
oirec = cur->bc_rec.b;
xfs_bmbt_disk_set_all(&nrec, &cur->bc_rec.b); xfs_bmbt_disk_set_all(&nrec, &cur->bc_rec.b);
ncur = NULL; ncur = NULL;
pcur = cur; pcur = cur;
...@@ -2073,13 +2086,11 @@ xfs_bmbt_insert( ...@@ -2073,13 +2086,11 @@ xfs_bmbt_insert(
&i))) { &i))) {
if (pcur != cur) if (pcur != cur)
xfs_btree_del_cursor(pcur, XFS_BTREE_ERROR); xfs_btree_del_cursor(pcur, XFS_BTREE_ERROR);
goto error0; XFS_BMBT_TRACE_CURSOR(cur, ERROR);
return error;
} }
XFS_WANT_CORRUPTED_GOTO(i == 1, error0); XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
if (pcur != cur && (ncur || nbno == NULLFSBLOCK)) { if (pcur != cur && (ncur || nbno == NULLFSBLOCK)) {
/* allocating a new root is effectively a split */
if (cur->bc_nlevels != pcur->bc_nlevels)
splits++;
cur->bc_nlevels = pcur->bc_nlevels; cur->bc_nlevels = pcur->bc_nlevels;
cur->bc_private.b.allocated += cur->bc_private.b.allocated +=
pcur->bc_private.b.allocated; pcur->bc_private.b.allocated;
...@@ -2093,21 +2104,10 @@ xfs_bmbt_insert( ...@@ -2093,21 +2104,10 @@ xfs_bmbt_insert(
xfs_btree_del_cursor(pcur, XFS_BTREE_NOERROR); xfs_btree_del_cursor(pcur, XFS_BTREE_NOERROR);
} }
if (ncur) { if (ncur) {
splits++;
pcur = ncur; pcur = ncur;
ncur = NULL; ncur = NULL;
} }
} while (nbno != NULLFSBLOCK); } while (nbno != NULLFSBLOCK);
if (splits > 1) {
/* revalidate the old cursor as we had a multi-level split */
error = xfs_bmbt_lookup_eq(cur, oirec.br_startoff,
oirec.br_startblock, oirec.br_blockcount, &i);
if (error)
goto error0;
ASSERT(i == 1);
}
XFS_BMBT_TRACE_CURSOR(cur, EXIT); XFS_BMBT_TRACE_CURSOR(cur, EXIT);
*stat = i; *stat = i;
return 0; return 0;
...@@ -2254,7 +2254,9 @@ xfs_bmbt_newroot( ...@@ -2254,7 +2254,9 @@ xfs_bmbt_newroot(
#endif #endif
args.fsbno = be64_to_cpu(*pp); args.fsbno = be64_to_cpu(*pp);
args.type = XFS_ALLOCTYPE_START_BNO; args.type = XFS_ALLOCTYPE_START_BNO;
} else } else if (cur->bc_private.b.flist->xbf_low)
args.type = XFS_ALLOCTYPE_START_BNO;
else
args.type = XFS_ALLOCTYPE_NEAR_BNO; args.type = XFS_ALLOCTYPE_NEAR_BNO;
if ((error = xfs_alloc_vextent(&args))) { if ((error = xfs_alloc_vextent(&args))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR); XFS_BMBT_TRACE_CURSOR(cur, ERROR);
......
...@@ -889,9 +889,9 @@ xfs_buf_item_relse( ...@@ -889,9 +889,9 @@ xfs_buf_item_relse(
} }
#ifdef XFS_TRANS_DEBUG #ifdef XFS_TRANS_DEBUG
kmem_free(bip->bli_orig, XFS_BUF_COUNT(bp)); kmem_free(bip->bli_orig);
bip->bli_orig = NULL; bip->bli_orig = NULL;
kmem_free(bip->bli_logged, XFS_BUF_COUNT(bp) / NBBY); kmem_free(bip->bli_logged);
bip->bli_logged = NULL; bip->bli_logged = NULL;
#endif /* XFS_TRANS_DEBUG */ #endif /* XFS_TRANS_DEBUG */
...@@ -1138,9 +1138,9 @@ xfs_buf_iodone( ...@@ -1138,9 +1138,9 @@ xfs_buf_iodone(
xfs_trans_delete_ail(mp, (xfs_log_item_t *)bip); xfs_trans_delete_ail(mp, (xfs_log_item_t *)bip);
#ifdef XFS_TRANS_DEBUG #ifdef XFS_TRANS_DEBUG
kmem_free(bip->bli_orig, XFS_BUF_COUNT(bp)); kmem_free(bip->bli_orig);
bip->bli_orig = NULL; bip->bli_orig = NULL;
kmem_free(bip->bli_logged, XFS_BUF_COUNT(bp) / NBBY); kmem_free(bip->bli_logged);
bip->bli_logged = NULL; bip->bli_logged = NULL;
#endif /* XFS_TRANS_DEBUG */ #endif /* XFS_TRANS_DEBUG */
......
...@@ -78,6 +78,7 @@ struct xfs_mount_args { ...@@ -78,6 +78,7 @@ struct xfs_mount_args {
#define XFSMNT_IOSIZE 0x00002000 /* optimize for I/O size */ #define XFSMNT_IOSIZE 0x00002000 /* optimize for I/O size */
#define XFSMNT_OSYNCISOSYNC 0x00004000 /* o_sync is REALLY o_sync */ #define XFSMNT_OSYNCISOSYNC 0x00004000 /* o_sync is REALLY o_sync */
/* (osyncisdsync is default) */ /* (osyncisdsync is default) */
#define XFSMNT_NOATTR2 0x00008000 /* turn off ATTR2 EA format */
#define XFSMNT_32BITINODES 0x00200000 /* restrict inodes to 32 #define XFSMNT_32BITINODES 0x00200000 /* restrict inodes to 32
* bits of address space */ * bits of address space */
#define XFSMNT_GQUOTA 0x00400000 /* group quota accounting */ #define XFSMNT_GQUOTA 0x00400000 /* group quota accounting */
......
This diff is collapsed.
...@@ -98,6 +98,15 @@ typedef struct xfs_da_node_entry xfs_da_node_entry_t; ...@@ -98,6 +98,15 @@ typedef struct xfs_da_node_entry xfs_da_node_entry_t;
* Btree searching and modification structure definitions. * Btree searching and modification structure definitions.
*========================================================================*/ *========================================================================*/
/*
* Search comparison results
*/
enum xfs_dacmp {
XFS_CMP_DIFFERENT, /* names are completely different */
XFS_CMP_EXACT, /* names are exactly the same */
XFS_CMP_CASE /* names are same but differ in case */
};
/* /*
* Structure to ease passing around component names. * Structure to ease passing around component names.
*/ */
...@@ -123,12 +132,19 @@ typedef struct xfs_da_args { ...@@ -123,12 +132,19 @@ typedef struct xfs_da_args {
int index2; /* index of 2nd attr in blk */ int index2; /* index of 2nd attr in blk */
xfs_dablk_t rmtblkno2; /* remote attr value starting blkno */ xfs_dablk_t rmtblkno2; /* remote attr value starting blkno */
int rmtblkcnt2; /* remote attr value block count */ int rmtblkcnt2; /* remote attr value block count */
unsigned char justcheck; /* T/F: check for ok with no space */ int op_flags; /* operation flags */
unsigned char rename; /* T/F: this is an atomic rename op */ enum xfs_dacmp cmpresult; /* name compare result for lookups */
unsigned char addname; /* T/F: this is an add operation */
unsigned char oknoent; /* T/F: ok to return ENOENT, else die */
} xfs_da_args_t; } xfs_da_args_t;
/*
* Operation flags:
*/
#define XFS_DA_OP_JUSTCHECK 0x0001 /* check for ok with no space */
#define XFS_DA_OP_RENAME 0x0002 /* this is an atomic rename op */
#define XFS_DA_OP_ADDNAME 0x0004 /* this is an add operation */
#define XFS_DA_OP_OKNOENT 0x0008 /* lookup/add op, ENOENT ok, else die */
#define XFS_DA_OP_CILOOKUP 0x0010 /* lookup to return CI name if found */
/* /*
* Structure to describe buffer(s) for a block. * Structure to describe buffer(s) for a block.
* This is needed in the directory version 2 format case, when * This is needed in the directory version 2 format case, when
...@@ -201,6 +217,14 @@ typedef struct xfs_da_state { ...@@ -201,6 +217,14 @@ typedef struct xfs_da_state {
(uint)(XFS_DA_LOGOFF(BASE, ADDR)), \ (uint)(XFS_DA_LOGOFF(BASE, ADDR)), \
(uint)(XFS_DA_LOGOFF(BASE, ADDR)+(SIZE)-1) (uint)(XFS_DA_LOGOFF(BASE, ADDR)+(SIZE)-1)
/*
* Name ops for directory and/or attr name operations
*/
struct xfs_nameops {
xfs_dahash_t (*hashname)(struct xfs_name *);
enum xfs_dacmp (*compname)(struct xfs_da_args *, const char *, int);
};
#ifdef __KERNEL__ #ifdef __KERNEL__
/*======================================================================== /*========================================================================
...@@ -249,6 +273,10 @@ int xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, ...@@ -249,6 +273,10 @@ int xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,
xfs_dabuf_t *dead_buf); xfs_dabuf_t *dead_buf);
uint xfs_da_hashname(const uchar_t *name_string, int name_length); uint xfs_da_hashname(const uchar_t *name_string, int name_length);
enum xfs_dacmp xfs_da_compname(struct xfs_da_args *args,
const char *name, int len);
xfs_da_state_t *xfs_da_state_alloc(void); xfs_da_state_t *xfs_da_state_alloc(void);
void xfs_da_state_free(xfs_da_state_t *state); void xfs_da_state_free(xfs_da_state_t *state);
......
...@@ -116,7 +116,7 @@ xfs_swapext( ...@@ -116,7 +116,7 @@ xfs_swapext(
out_put_file: out_put_file:
fput(file); fput(file);
out_free_sxp: out_free_sxp:
kmem_free(sxp, sizeof(xfs_swapext_t)); kmem_free(sxp);
out: out:
return error; return error;
} }
...@@ -381,6 +381,6 @@ xfs_swap_extents( ...@@ -381,6 +381,6 @@ xfs_swap_extents(
xfs_iunlock(tip, lock_flags); xfs_iunlock(tip, lock_flags);
} }
if (tempifp != NULL) if (tempifp != NULL)
kmem_free(tempifp, sizeof(xfs_ifork_t)); kmem_free(tempifp);
return error; return error;
} }
This diff is collapsed.
...@@ -74,7 +74,8 @@ extern int xfs_dir_createname(struct xfs_trans *tp, struct xfs_inode *dp, ...@@ -74,7 +74,8 @@ extern int xfs_dir_createname(struct xfs_trans *tp, struct xfs_inode *dp,
xfs_fsblock_t *first, xfs_fsblock_t *first,
struct xfs_bmap_free *flist, xfs_extlen_t tot); struct xfs_bmap_free *flist, xfs_extlen_t tot);
extern int xfs_dir_lookup(struct xfs_trans *tp, struct xfs_inode *dp, extern int xfs_dir_lookup(struct xfs_trans *tp, struct xfs_inode *dp,
struct xfs_name *name, xfs_ino_t *inum); struct xfs_name *name, xfs_ino_t *inum,
struct xfs_name *ci_name);
extern int xfs_dir_removename(struct xfs_trans *tp, struct xfs_inode *dp, extern int xfs_dir_removename(struct xfs_trans *tp, struct xfs_inode *dp,
struct xfs_name *name, xfs_ino_t ino, struct xfs_name *name, xfs_ino_t ino,
xfs_fsblock_t *first, xfs_fsblock_t *first,
...@@ -99,4 +100,7 @@ extern int xfs_dir2_isleaf(struct xfs_trans *tp, struct xfs_inode *dp, ...@@ -99,4 +100,7 @@ extern int xfs_dir2_isleaf(struct xfs_trans *tp, struct xfs_inode *dp,
extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db, extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db,
struct xfs_dabuf *bp); struct xfs_dabuf *bp);
extern int xfs_dir_cilookup_result(struct xfs_da_args *args, const char *name,
int len);
#endif /* __XFS_DIR2_H__ */ #endif /* __XFS_DIR2_H__ */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -166,6 +166,6 @@ typedef enum { ...@@ -166,6 +166,6 @@ typedef enum {
#define FILP_DELAY_FLAG(filp) ((filp->f_flags&(O_NDELAY|O_NONBLOCK)) ? \ #define FILP_DELAY_FLAG(filp) ((filp->f_flags&(O_NDELAY|O_NONBLOCK)) ? \
DM_FLAGS_NDELAY : 0) DM_FLAGS_NDELAY : 0)
#define AT_DELAY_FLAG(f) ((f&ATTR_NONBLOCK) ? DM_FLAGS_NDELAY : 0) #define AT_DELAY_FLAG(f) ((f & XFS_ATTR_NONBLOCK) ? DM_FLAGS_NDELAY : 0)
#endif /* __XFS_DMAPI_H__ */ #endif /* __XFS_DMAPI_H__ */
This diff is collapsed.
...@@ -127,7 +127,6 @@ extern void xfs_corruption_error(char *tag, int level, struct xfs_mount *mp, ...@@ -127,7 +127,6 @@ extern void xfs_corruption_error(char *tag, int level, struct xfs_mount *mp,
#if (defined(DEBUG) || defined(INDUCE_IO_ERROR)) #if (defined(DEBUG) || defined(INDUCE_IO_ERROR))
extern int xfs_error_test(int, int *, char *, int, char *, unsigned long); extern int xfs_error_test(int, int *, char *, int, char *, unsigned long);
extern void xfs_error_test_init(void);
#define XFS_NUM_INJECT_ERROR 10 #define XFS_NUM_INJECT_ERROR 10
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment