From c2676ef801f50cc759d205a89adbf733c798d052 Mon Sep 17 00:00:00 2001 From: David Reynolds Date: Thu, 8 Mar 2018 18:54:12 -0500 Subject: orangefs: bug fix for a race condition when getting a slot When a slot becomes free, call wake_up_locked regardless of the number of slots available. Without this patch, wake_up_locked is only called when going from no free slots to one. This means that there is a chance a waiting task will not be woken up. In many cases, the system will bounce between 0 and 1 free slots, and the waiting tasks will be woken up. But if there is still a waiting task and another slot becomes available before the number of free slots reaches zero, that waiting task may never be woken up since the number of free slots may never reach zero again. The bug behavior is easy to reproduce with the following script, where /mnt/orangefs is an OrangeFS file system. for i in {1..100}; do for j in {1..20}; do dd if=/dev/zero of=/mnt/orangefs/tmp$j bs=32768 count=32 & done wait done Signed-off-by: David Reynolds Reviewed-by: Martin Brandenburg Signed-off-by: Mike Marshall --- fs/orangefs/orangefs-bufmap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'fs/orangefs') diff --git a/fs/orangefs/orangefs-bufmap.c b/fs/orangefs/orangefs-bufmap.c index 59f444d..4f92702 100644 --- a/fs/orangefs/orangefs-bufmap.c +++ b/fs/orangefs/orangefs-bufmap.c @@ -71,9 +71,9 @@ static void put(struct slot_map *m, int slot) spin_lock(&m->q.lock); __clear_bit(slot, m->map); v = ++m->c; - if (unlikely(v == 1)) /* no free slots -> one free slot */ + if (v > 0) wake_up_locked(&m->q); - else if (unlikely(v == -1)) /* finished dying */ + if (unlikely(v == -1)) /* finished dying */ wake_up_all_locked(&m->q); spin_unlock(&m->q.lock); } -- cgit v1.1 From 81e3d0253f87d369a1d957eb3173fd596126383c Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 26 Jan 2018 19:42:47 +0000 Subject: orangefs: replace vmalloc and memset with vzalloc Use vzalloc instead of the vmalloc, memset combo Signed-off-by: Colin Ian King Signed-off-by: Mike Marshall --- fs/orangefs/devorangefs-req.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'fs/orangefs') diff --git a/fs/orangefs/devorangefs-req.c b/fs/orangefs/devorangefs-req.c index b03057a..319cf9d 100644 --- a/fs/orangefs/devorangefs-req.c +++ b/fs/orangefs/devorangefs-req.c @@ -463,11 +463,10 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, if (op->downcall.type != ORANGEFS_VFS_OP_READDIR) goto wakeup; - op->downcall.trailer_buf = vmalloc(op->downcall.trailer_size); + op->downcall.trailer_buf = vzalloc(op->downcall.trailer_size); if (!op->downcall.trailer_buf) goto Enomem; - memset(op->downcall.trailer_buf, 0, op->downcall.trailer_size); if (!copy_from_iter_full(op->downcall.trailer_buf, op->downcall.trailer_size, iter)) { gossip_err("%s: failed to copy trailer.\n", __func__); -- cgit v1.1 From dbcb5e7fc470c9daec9cb4ae463670f2047163e3 Mon Sep 17 00:00:00 2001 From: Martin Brandenburg Date: Tue, 20 Mar 2018 17:00:12 +0000 Subject: orangefs: open code short single-use functions Signed-off-by: Martin Brandenburg Signed-off-by: Mike Marshall --- fs/orangefs/file.c | 95 +++++++++++------------------------------------------- 1 file changed, 19 insertions(+), 76 deletions(-) (limited to 'fs/orangefs') diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index 0d228cd..3a7319a 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -42,70 +42,6 @@ static int flush_racache(struct inode *inode) } /* - * Copy to client-core's address space from the buffers specified - * by the iovec upto total_size bytes. - * NOTE: the iovector can either contain addresses which - * can futher be kernel-space or user-space addresses. - * or it can pointers to struct page's - */ -static int precopy_buffers(int buffer_index, - struct iov_iter *iter, - size_t total_size) -{ - int ret = 0; - /* - * copy data from application/kernel by pulling it out - * of the iovec. - */ - - - if (total_size) { - ret = orangefs_bufmap_copy_from_iovec(iter, - buffer_index, - total_size); - if (ret < 0) - gossip_err("%s: Failed to copy-in buffers. Please make sure that the pvfs2-client is running. %ld\n", - __func__, - (long)ret); - } - - if (ret < 0) - gossip_err("%s: Failed to copy-in buffers. Please make sure that the pvfs2-client is running. %ld\n", - __func__, - (long)ret); - return ret; -} - -/* - * Copy from client-core's address space to the buffers specified - * by the iovec upto total_size bytes. - * NOTE: the iovector can either contain addresses which - * can futher be kernel-space or user-space addresses. - * or it can pointers to struct page's - */ -static int postcopy_buffers(int buffer_index, - struct iov_iter *iter, - size_t total_size) -{ - int ret = 0; - /* - * copy data to application/kernel by pushing it out to - * the iovec. NOTE; target buffers can be addresses or - * struct page pointers. - */ - if (total_size) { - ret = orangefs_bufmap_copy_to_iovec(iter, - buffer_index, - total_size); - if (ret < 0) - gossip_err("%s: Failed to copy-out buffers. Please make sure that the pvfs2-client is running (%ld)\n", - __func__, - (long)ret); - } - return ret; -} - -/* * Post and wait for the I/O upcall to finish */ static ssize_t wait_for_direct_io(enum ORANGEFS_io_type type, struct inode *inode, @@ -157,14 +93,15 @@ populate_shared_memory: total_size); /* * Stage 1: copy the buffers into client-core's address space - * precopy_buffers only pertains to writes. */ - if (type == ORANGEFS_IO_WRITE) { - ret = precopy_buffers(buffer_index, - iter, - total_size); - if (ret < 0) + if (type == ORANGEFS_IO_WRITE && total_size) { + ret = orangefs_bufmap_copy_from_iovec(iter, buffer_index, + total_size); + if (ret < 0) { + gossip_err("%s: Failed to copy-in buffers. Please make sure that the pvfs2-client is running. %ld\n", + __func__, (long)ret); goto out; + } } gossip_debug(GOSSIP_FILE_DEBUG, @@ -260,14 +197,20 @@ populate_shared_memory: /* * Stage 3: Post copy buffers from client-core's address space - * postcopy_buffers only pertains to reads. */ - if (type == ORANGEFS_IO_READ) { - ret = postcopy_buffers(buffer_index, - iter, - new_op->downcall.resp.io.amt_complete); - if (ret < 0) + if (type == ORANGEFS_IO_READ && new_op->downcall.resp.io.amt_complete) { + /* + * NOTE: the iovector can either contain addresses which + * can futher be kernel-space or user-space addresses. + * or it can pointers to struct page's + */ + ret = orangefs_bufmap_copy_to_iovec(iter, buffer_index, + new_op->downcall.resp.io.amt_complete); + if (ret < 0) { + gossip_err("%s: Failed to copy-out buffers. Please make sure that the pvfs2-client is running (%ld)\n", + __func__, (long)ret); goto out; + } } gossip_debug(GOSSIP_FILE_DEBUG, "%s(%pU): Amount %s, returned by the sys-io call:%d\n", -- cgit v1.1 From a5135eeab2e5ca1b94f34dcb772cb30f9f390efc Mon Sep 17 00:00:00 2001 From: Martin Brandenburg Date: Tue, 3 Apr 2018 16:27:12 +0000 Subject: orangefs: implement vm_ops->fault Must retrieve size before running filemap_fault so the kernel has an up-to-date size. This should have been caught by xfstests generic/246, but it was masked by orangefs_new_inode, which set i_size to PAGE_SIZE. When nothing caused a getattr prior to a pagefault, i_size was still PAGE_SIZE. Since xfstests only read 10 bytes, it did not catch this bug. When orangefs_new_inode was modified to perform a getattr instead, i_size was set to zero, as it was a newly created file. Then orangefs_file_write_iter did NOT set i_size. Instead it invalidated the attribute cache, which should have caused the next caller to retrieve i_size. But the fault handler did not know it was supposed to retrieve i_size. So during xfstests, i_size was still zero, and filemap_fault returned VM_FAULT_SIGBUS. Fixes xfstests generic/452. Signed-off-by: Martin Brandenburg Signed-off-by: Mike Marshall --- fs/orangefs/file.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'fs/orangefs') diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index 3a7319a..26358ef 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -528,6 +528,28 @@ static long orangefs_ioctl(struct file *file, unsigned int cmd, unsigned long ar return ret; } +static int orangefs_fault(struct vm_fault *vmf) +{ + struct file *file = vmf->vma->vm_file; + int rc; + rc = orangefs_inode_getattr(file->f_mapping->host, 0, 1, + STATX_SIZE); + if (rc == -ESTALE) + rc = -EIO; + if (rc) { + gossip_err("%s: orangefs_inode_getattr failed, " + "rc:%d:.\n", __func__, rc); + return rc; + } + return filemap_fault(vmf); +} + +const struct vm_operations_struct orangefs_file_vm_ops = { + .fault = orangefs_fault, + .map_pages = filemap_map_pages, + .page_mkwrite = filemap_page_mkwrite, +}; + /* * Memory map a region of a file. */ @@ -539,12 +561,16 @@ static int orangefs_file_mmap(struct file *file, struct vm_area_struct *vma) (char *)file->f_path.dentry->d_name.name : (char *)"Unknown")); + if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE)) + return -EINVAL; + /* set the sequential readahead hint */ vma->vm_flags |= VM_SEQ_READ; vma->vm_flags &= ~VM_RAND_READ; - /* Use readonly mmap since we cannot support writable maps. */ - return generic_file_readonly_mmap(file, vma); + file_accessed(file); + vma->vm_ops = &orangefs_file_vm_ops; + return 0; } #define mapping_nrpages(idata) ((idata)->nrpages) -- cgit v1.1 From bdd6f083586ff17eb3959cca88212fdb60ca53d1 Mon Sep 17 00:00:00 2001 From: Martin Brandenburg Date: Tue, 3 Apr 2018 16:27:13 +0000 Subject: orangefs: make several *_operations structs static Signed-off-by: Martin Brandenburg Signed-off-by: Mike Marshall --- fs/orangefs/devorangefs-req.c | 52 +++++++++++++++++++++---------------------- fs/orangefs/inode.c | 4 ++-- fs/orangefs/orangefs-kernel.h | 3 --- 3 files changed, 28 insertions(+), 31 deletions(-) (limited to 'fs/orangefs') diff --git a/fs/orangefs/devorangefs-req.c b/fs/orangefs/devorangefs-req.c index 319cf9d..66369ec 100644 --- a/fs/orangefs/devorangefs-req.c +++ b/fs/orangefs/devorangefs-req.c @@ -778,9 +778,35 @@ static long orangefs_devreq_compat_ioctl(struct file *filp, unsigned int cmd, #endif /* CONFIG_COMPAT is in .config */ +static __poll_t orangefs_devreq_poll(struct file *file, + struct poll_table_struct *poll_table) +{ + __poll_t poll_revent_mask = 0; + + poll_wait(file, &orangefs_request_list_waitq, poll_table); + + if (!list_empty(&orangefs_request_list)) + poll_revent_mask |= EPOLLIN; + return poll_revent_mask; +} + /* the assigned character device major number */ static int orangefs_dev_major; +static const struct file_operations orangefs_devreq_file_operations = { + .owner = THIS_MODULE, + .read = orangefs_devreq_read, + .write_iter = orangefs_devreq_write_iter, + .open = orangefs_devreq_open, + .release = orangefs_devreq_release, + .unlocked_ioctl = orangefs_devreq_ioctl, + +#ifdef CONFIG_COMPAT /* CONFIG_COMPAT is in .config */ + .compat_ioctl = orangefs_devreq_compat_ioctl, +#endif + .poll = orangefs_devreq_poll +}; + /* * Initialize orangefs device specific state: * Must be called at module load time only @@ -813,29 +839,3 @@ void orangefs_dev_cleanup(void) "*** /dev/%s character device unregistered ***\n", ORANGEFS_REQDEVICE_NAME); } - -static __poll_t orangefs_devreq_poll(struct file *file, - struct poll_table_struct *poll_table) -{ - __poll_t poll_revent_mask = 0; - - poll_wait(file, &orangefs_request_list_waitq, poll_table); - - if (!list_empty(&orangefs_request_list)) - poll_revent_mask |= EPOLLIN; - return poll_revent_mask; -} - -const struct file_operations orangefs_devreq_file_operations = { - .owner = THIS_MODULE, - .read = orangefs_devreq_read, - .write_iter = orangefs_devreq_write_iter, - .open = orangefs_devreq_open, - .release = orangefs_devreq_release, - .unlocked_ioctl = orangefs_devreq_ioctl, - -#ifdef CONFIG_COMPAT /* CONFIG_COMPAT is in .config */ - .compat_ioctl = orangefs_devreq_compat_ioctl, -#endif - .poll = orangefs_devreq_poll -}; diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c index fe1d705..79c61da 100644 --- a/fs/orangefs/inode.c +++ b/fs/orangefs/inode.c @@ -138,7 +138,7 @@ static ssize_t orangefs_direct_IO(struct kiocb *iocb, } /** ORANGEFS2 implementation of address space operations */ -const struct address_space_operations orangefs_address_operations = { +static const struct address_space_operations orangefs_address_operations = { .readpage = orangefs_readpage, .readpages = orangefs_readpages, .invalidatepage = orangefs_invalidatepage, @@ -307,7 +307,7 @@ int orangefs_update_time(struct inode *inode, struct timespec *time, int flags) } /* ORANGEDS2 implementation of VFS inode operations for files */ -const struct inode_operations orangefs_file_inode_operations = { +static const struct inode_operations orangefs_file_inode_operations = { .get_acl = orangefs_get_acl, .set_acl = orangefs_set_acl, .setattr = orangefs_setattr, diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index eebbaec..f49d53d 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -487,14 +487,11 @@ extern struct list_head *orangefs_htable_ops_in_progress; extern spinlock_t orangefs_htable_ops_in_progress_lock; extern int hash_table_size; -extern const struct address_space_operations orangefs_address_operations; -extern const struct inode_operations orangefs_file_inode_operations; extern const struct file_operations orangefs_file_operations; extern const struct inode_operations orangefs_symlink_inode_operations; extern const struct inode_operations orangefs_dir_inode_operations; extern const struct file_operations orangefs_dir_operations; extern const struct dentry_operations orangefs_dentry_operations; -extern const struct file_operations orangefs_devreq_file_operations; extern wait_queue_head_t orangefs_bufmap_init_waitq; -- cgit v1.1 From 209469d978ae91e460b37b32f2c2834d93e1ff13 Mon Sep 17 00:00:00 2001 From: Martin Brandenburg Date: Tue, 3 Apr 2018 16:27:14 +0000 Subject: orangefs: remove unused code Signed-off-by: Martin Brandenburg Signed-off-by: Mike Marshall --- fs/orangefs/orangefs-debug.h | 6 ---- fs/orangefs/orangefs-kernel.h | 77 ------------------------------------------- fs/orangefs/protocol.h | 45 ------------------------- 3 files changed, 128 deletions(-) (limited to 'fs/orangefs') diff --git a/fs/orangefs/orangefs-debug.h b/fs/orangefs/orangefs-debug.h index c7db56a..6e079d4 100644 --- a/fs/orangefs/orangefs-debug.h +++ b/fs/orangefs/orangefs-debug.h @@ -43,12 +43,6 @@ #define GOSSIP_MAX_NR 16 #define GOSSIP_MAX_DEBUG (((__u64)1 << GOSSIP_MAX_NR) - 1) -/*function prototypes*/ -__u64 ORANGEFS_kmod_eventlog_to_mask(const char *event_logging); -__u64 ORANGEFS_debug_eventlog_to_mask(const char *event_logging); -char *ORANGEFS_debug_mask_to_eventlog(__u64 mask); -char *ORANGEFS_kmod_mask_to_eventlog(__u64 mask); - /* a private internal type */ struct __keyword_mask_s { const char *keyword; diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index f49d53d..c29bb0e 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -65,11 +65,7 @@ #define ORANGEFS_REQDEVICE_NAME "pvfs2-req" #define ORANGEFS_DEVREQ_MAGIC 0x20030529 -#define ORANGEFS_LINK_MAX 0x000000FF #define ORANGEFS_PURGE_RETRY_COUNT 0x00000005 -#define ORANGEFS_MAX_NUM_OPTIONS 0x00000004 -#define ORANGEFS_MAX_MOUNT_OPT_LEN 0x00000080 -#define ORANGEFS_MAX_FSKEY_LEN 64 #define MAX_DEV_REQ_UPSIZE (2 * sizeof(__s32) + \ sizeof(__u64) + sizeof(struct orangefs_upcall_s)) @@ -113,15 +109,6 @@ extern struct posix_acl *orangefs_get_acl(struct inode *inode, int type); extern int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type); /* - * Redefine xtvec structure so that we could move helper functions out of - * the define - */ -struct xtvec { - __kernel_off_t xtv_off; /* must be off_t */ - __kernel_size_t xtv_len; /* must be size_t */ -}; - -/* * orangefs data structures */ struct orangefs_kernel_op_s { @@ -224,39 +211,6 @@ struct orangefs_sb_info_s { struct list_head list; }; -/* - * structure that holds the state of any async I/O operation issued - * through the VFS. Needed especially to handle cancellation requests - * or even completion notification so that the VFS client-side daemon - * can free up its vfs_request slots. - */ -struct orangefs_kiocb_s { - /* the pointer to the task that initiated the AIO */ - struct task_struct *tsk; - - /* pointer to the kiocb that kicked this operation */ - struct kiocb *kiocb; - - /* buffer index that was used for the I/O */ - struct orangefs_bufmap *bufmap; - int buffer_index; - - /* orangefs kernel operation type */ - struct orangefs_kernel_op_s *op; - - /* set to indicate the type of the operation */ - int rw; - - /* file offset */ - loff_t offset; - - /* and the count in bytes */ - size_t bytes_to_be_copied; - - ssize_t bytes_copied; - int needs_cleanup; -}; - struct orangefs_stats { unsigned long cache_hits; unsigned long cache_misses; @@ -305,21 +259,6 @@ static inline struct orangefs_khandle *get_khandle_from_ino(struct inode *inode) return &(ORANGEFS_I(inode)->refn.khandle); } -static inline ino_t get_ino_from_khandle(struct inode *inode) -{ - struct orangefs_khandle *khandle; - ino_t ino; - - khandle = get_khandle_from_ino(inode); - ino = orangefs_khandle_to_ino(khandle); - return ino; -} - -static inline ino_t get_parent_ino_from_dentry(struct dentry *dentry) -{ - return get_ino_from_khandle(dentry->d_parent->d_inode); -} - static inline int is_root_handle(struct inode *inode) { gossip_debug(GOSSIP_DCACHE_DEBUG, @@ -391,7 +330,6 @@ void fsid_key_table_finalize(void); /* * defined in inode.c */ -__u32 convert_to_orangefs_mask(unsigned long lite_mask); struct inode *orangefs_new_inode(struct super_block *sb, struct inode *dir, int mode, @@ -410,17 +348,6 @@ int orangefs_update_time(struct inode *, struct timespec *, int); /* * defined in xattr.c */ -int orangefs_setxattr(struct dentry *dentry, - const char *name, - const void *value, - size_t size, - int flags); - -ssize_t orangefs_getxattr(struct dentry *dentry, - const char *name, - void *buffer, - size_t size); - ssize_t orangefs_listxattr(struct dentry *dentry, char *buffer, size_t size); /* @@ -467,8 +394,6 @@ int orangefs_inode_check_changed(struct inode *inode); int orangefs_inode_setattr(struct inode *inode, struct iattr *iattr); -int orangefs_unmount_sb(struct super_block *sb); - bool orangefs_cancel_op_in_progress(struct orangefs_kernel_op_s *op); int orangefs_normalize_to_errno(__s32 error_code); @@ -493,8 +418,6 @@ extern const struct inode_operations orangefs_dir_inode_operations; extern const struct file_operations orangefs_dir_operations; extern const struct dentry_operations orangefs_dentry_operations; -extern wait_queue_head_t orangefs_bufmap_init_waitq; - /* * misc convenience macros */ diff --git a/fs/orangefs/protocol.h b/fs/orangefs/protocol.h index dc6e3e6..61ee8d6 100644 --- a/fs/orangefs/protocol.h +++ b/fs/orangefs/protocol.h @@ -5,11 +5,6 @@ #include #include -/* pvfs2-config.h ***********************************************************/ -#define ORANGEFS_VERSION_MAJOR 2 -#define ORANGEFS_VERSION_MINOR 9 -#define ORANGEFS_VERSION_SUB 0 - /* khandle stuff ***********************************************************/ /* @@ -70,16 +65,6 @@ static inline void ORANGEFS_khandle_from(struct orangefs_khandle *kh, } /* pvfs2-types.h ************************************************************/ -typedef __u32 ORANGEFS_uid; -typedef __u32 ORANGEFS_gid; -typedef __s32 ORANGEFS_fs_id; -typedef __u32 ORANGEFS_permissions; -typedef __u64 ORANGEFS_time; -typedef __s64 ORANGEFS_size; -typedef __u64 ORANGEFS_flags; -typedef __u64 ORANGEFS_ds_position; -typedef __s32 ORANGEFS_error; -typedef __s64 ORANGEFS_offset; #define ORANGEFS_SUPER_MAGIC 0x20030528 @@ -145,7 +130,6 @@ typedef __s64 ORANGEFS_offset; #define ORANGEFS_APPEND_FL FS_APPEND_FL #define ORANGEFS_NOATIME_FL FS_NOATIME_FL #define ORANGEFS_MIRROR_FL 0x01000000ULL -#define ORANGEFS_O_EXECUTE (1 << 0) #define ORANGEFS_FS_ID_NULL ((__s32)0) #define ORANGEFS_ATTR_SYS_UID (1 << 0) #define ORANGEFS_ATTR_SYS_GID (1 << 1) @@ -229,35 +213,6 @@ enum orangefs_ds_type { ORANGEFS_TYPE_INTERNAL = (1 << 5) /* for the server's private use */ }; -/* - * ORANGEFS_certificate simply stores a buffer with the buffer size. - * The buffer can be converted to an OpenSSL X509 struct for use. - */ -struct ORANGEFS_certificate { - __u32 buf_size; - unsigned char *buf; -}; - -/* - * A credential identifies a user and is signed by the client/user - * private key. - */ -struct ORANGEFS_credential { - __u32 userid; /* user id */ - __u32 num_groups; /* length of group_array */ - __u32 *group_array; /* groups for which the user is a member */ - char *issuer; /* alias of the issuing server */ - __u64 timeout; /* seconds after epoch to time out */ - __u32 sig_size; /* length of the signature in bytes */ - unsigned char *signature; /* digital signature */ - struct ORANGEFS_certificate certificate; /* user certificate buffer */ -}; -#define extra_size_ORANGEFS_credential (ORANGEFS_REQ_LIMIT_GROUPS * \ - sizeof(__u32) + \ - ORANGEFS_REQ_LIMIT_ISSUER + \ - ORANGEFS_REQ_LIMIT_SIGNATURE + \ - extra_size_ORANGEFS_certificate) - /* This structure is used by the VFS-client interaction alone */ struct ORANGEFS_keyval_pair { char key[ORANGEFS_MAX_XATTR_NAMELEN]; -- cgit v1.1