diff options
Diffstat (limited to 'fs/hfsplus')
-rw-r--r-- | fs/hfsplus/bfind.c | 4 | ||||
-rw-r--r-- | fs/hfsplus/catalog.c | 3 | ||||
-rw-r--r-- | fs/hfsplus/dir.c | 4 | ||||
-rw-r--r-- | fs/hfsplus/inode.c | 6 | ||||
-rw-r--r-- | fs/hfsplus/ioctl.c | 12 | ||||
-rw-r--r-- | fs/hfsplus/xattr.c | 86 | ||||
-rw-r--r-- | fs/hfsplus/xattr.h | 22 | ||||
-rw-r--r-- | fs/hfsplus/xattr_security.c | 38 | ||||
-rw-r--r-- | fs/hfsplus/xattr_trusted.c | 37 | ||||
-rw-r--r-- | fs/hfsplus/xattr_user.c | 35 |
10 files changed, 100 insertions, 147 deletions
diff --git a/fs/hfsplus/bfind.c b/fs/hfsplus/bfind.c index c1422d9..528e38b 100644 --- a/fs/hfsplus/bfind.c +++ b/fs/hfsplus/bfind.c @@ -118,9 +118,7 @@ int __hfs_brec_find(struct hfs_bnode *bnode, struct hfs_find_data *fd, int b, e; int res; - if (!rec_found) - BUG(); - + BUG_ON(!rec_found); b = 0; e = bnode->num_recs - 1; res = -ENOENT; diff --git a/fs/hfsplus/catalog.c b/fs/hfsplus/catalog.c index 7892e6f..022974a 100644 --- a/fs/hfsplus/catalog.c +++ b/fs/hfsplus/catalog.c @@ -350,10 +350,11 @@ int hfsplus_delete_cat(u32 cnid, struct inode *dir, struct qstr *str) &fd.search_key->cat.name.unicode, off + 2, len); fd.search_key->key_len = cpu_to_be16(6 + len); - } else + } else { err = hfsplus_cat_build_key(sb, fd.search_key, dir->i_ino, str); if (unlikely(err)) goto out; + } err = hfs_brec_find(&fd, hfs_find_rec_by_key); if (err) diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index f0235c1..3074609 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c @@ -434,7 +434,7 @@ static int hfsplus_symlink(struct inode *dir, struct dentry *dentry, { struct hfsplus_sb_info *sbi = HFSPLUS_SB(dir->i_sb); struct inode *inode; - int res = -ENOSPC; + int res = -ENOMEM; mutex_lock(&sbi->vh_mutex); inode = hfsplus_new_inode(dir->i_sb, S_IFLNK | S_IRWXUGO); @@ -476,7 +476,7 @@ static int hfsplus_mknod(struct inode *dir, struct dentry *dentry, { struct hfsplus_sb_info *sbi = HFSPLUS_SB(dir->i_sb); struct inode *inode; - int res = -ENOSPC; + int res = -ENOMEM; mutex_lock(&sbi->vh_mutex); inode = hfsplus_new_inode(dir->i_sb, mode); diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index a43811f..b0afedb 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -253,6 +253,12 @@ static int hfsplus_setattr(struct dentry *dentry, struct iattr *attr) if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size != i_size_read(inode)) { inode_dio_wait(inode); + if (attr->ia_size > inode->i_size) { + error = generic_cont_expand_simple(inode, + attr->ia_size); + if (error) + return error; + } truncate_setsize(inode, attr->ia_size); hfsplus_file_truncate(inode); } diff --git a/fs/hfsplus/ioctl.c b/fs/hfsplus/ioctl.c index d3ff5cc..8e98f5d 100644 --- a/fs/hfsplus/ioctl.c +++ b/fs/hfsplus/ioctl.c @@ -76,7 +76,7 @@ static int hfsplus_ioctl_setflags(struct file *file, int __user *user_flags) { struct inode *inode = file_inode(file); struct hfsplus_inode_info *hip = HFSPLUS_I(inode); - unsigned int flags; + unsigned int flags, new_fl = 0; int err = 0; err = mnt_want_write_file(file); @@ -110,14 +110,12 @@ static int hfsplus_ioctl_setflags(struct file *file, int __user *user_flags) } if (flags & FS_IMMUTABLE_FL) - inode->i_flags |= S_IMMUTABLE; - else - inode->i_flags &= ~S_IMMUTABLE; + new_fl |= S_IMMUTABLE; if (flags & FS_APPEND_FL) - inode->i_flags |= S_APPEND; - else - inode->i_flags &= ~S_APPEND; + new_fl |= S_APPEND; + + inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND); if (flags & FS_NODUMP_FL) hip->userflags |= HFSPLUS_FLG_NODUMP; diff --git a/fs/hfsplus/xattr.c b/fs/hfsplus/xattr.c index d98094a..89f262d 100644 --- a/fs/hfsplus/xattr.c +++ b/fs/hfsplus/xattr.c @@ -44,7 +44,7 @@ static int strcmp_xattr_acl(const char *name) return -1; } -static inline int is_known_namespace(const char *name) +static bool is_known_namespace(const char *name) { if (strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN) && strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) && @@ -424,6 +424,28 @@ static int copy_name(char *buffer, const char *xattr_name, int name_len) return len; } +int hfsplus_setxattr(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags, + const char *prefix, size_t prefixlen) +{ + char *xattr_name; + int res; + + if (!strcmp(name, "")) + return -EINVAL; + + xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1, + GFP_KERNEL); + if (!xattr_name) + return -ENOMEM; + strcpy(xattr_name, prefix); + strcpy(xattr_name + prefixlen, name); + res = __hfsplus_setxattr(dentry->d_inode, xattr_name, value, size, + flags); + kfree(xattr_name); + return res; +} + static ssize_t hfsplus_getxattr_finder_info(struct inode *inode, void *value, size_t size) { @@ -560,6 +582,30 @@ failed_getxattr_init: return res; } +ssize_t hfsplus_getxattr(struct dentry *dentry, const char *name, + void *value, size_t size, + const char *prefix, size_t prefixlen) +{ + int res; + char *xattr_name; + + if (!strcmp(name, "")) + return -EINVAL; + + xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1, + GFP_KERNEL); + if (!xattr_name) + return -ENOMEM; + + strcpy(xattr_name, prefix); + strcpy(xattr_name + prefixlen, name); + + res = __hfsplus_getxattr(dentry->d_inode, xattr_name, value, size); + kfree(xattr_name); + return res; + +} + static inline int can_list(const char *xattr_name) { if (!xattr_name) @@ -806,9 +852,6 @@ end_removexattr: static int hfsplus_osx_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size, int type) { - char *xattr_name; - int res; - if (!strcmp(name, "")) return -EINVAL; @@ -818,24 +861,19 @@ static int hfsplus_osx_getxattr(struct dentry *dentry, const char *name, */ if (is_known_namespace(name)) return -EOPNOTSUPP; - xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN - + XATTR_MAC_OSX_PREFIX_LEN + 1, GFP_KERNEL); - if (!xattr_name) - return -ENOMEM; - strcpy(xattr_name, XATTR_MAC_OSX_PREFIX); - strcpy(xattr_name + XATTR_MAC_OSX_PREFIX_LEN, name); - res = hfsplus_getxattr(dentry, xattr_name, buffer, size); - kfree(xattr_name); - return res; + /* + * osx is the namespace we use to indicate an unprefixed + * attribute on the filesystem (like the ones that OS X + * creates), so we pass the name through unmodified (after + * ensuring it doesn't conflict with another namespace). + */ + return __hfsplus_getxattr(dentry->d_inode, name, buffer, size); } static int hfsplus_osx_setxattr(struct dentry *dentry, const char *name, const void *buffer, size_t size, int flags, int type) { - char *xattr_name; - int res; - if (!strcmp(name, "")) return -EINVAL; @@ -845,16 +883,14 @@ static int hfsplus_osx_setxattr(struct dentry *dentry, const char *name, */ if (is_known_namespace(name)) return -EOPNOTSUPP; - xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN - + XATTR_MAC_OSX_PREFIX_LEN + 1, GFP_KERNEL); - if (!xattr_name) - return -ENOMEM; - strcpy(xattr_name, XATTR_MAC_OSX_PREFIX); - strcpy(xattr_name + XATTR_MAC_OSX_PREFIX_LEN, name); - res = hfsplus_setxattr(dentry, xattr_name, buffer, size, flags); - kfree(xattr_name); - return res; + /* + * osx is the namespace we use to indicate an unprefixed + * attribute on the filesystem (like the ones that OS X + * creates), so we pass the name through unmodified (after + * ensuring it doesn't conflict with another namespace). + */ + return __hfsplus_setxattr(dentry->d_inode, name, buffer, size, flags); } static size_t hfsplus_osx_listxattr(struct dentry *dentry, char *list, diff --git a/fs/hfsplus/xattr.h b/fs/hfsplus/xattr.h index 288530c..f9b0955 100644 --- a/fs/hfsplus/xattr.h +++ b/fs/hfsplus/xattr.h @@ -21,22 +21,16 @@ extern const struct xattr_handler *hfsplus_xattr_handlers[]; int __hfsplus_setxattr(struct inode *inode, const char *name, const void *value, size_t size, int flags); -static inline int hfsplus_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags) -{ - return __hfsplus_setxattr(dentry->d_inode, name, value, size, flags); -} +int hfsplus_setxattr(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags, + const char *prefix, size_t prefixlen); ssize_t __hfsplus_getxattr(struct inode *inode, const char *name, - void *value, size_t size); - -static inline ssize_t hfsplus_getxattr(struct dentry *dentry, - const char *name, - void *value, - size_t size) -{ - return __hfsplus_getxattr(dentry->d_inode, name, value, size); -} + void *value, size_t size); + +ssize_t hfsplus_getxattr(struct dentry *dentry, const char *name, + void *value, size_t size, + const char *prefix, size_t prefixlen); ssize_t hfsplus_listxattr(struct dentry *dentry, char *buffer, size_t size); diff --git a/fs/hfsplus/xattr_security.c b/fs/hfsplus/xattr_security.c index 6ec5e10..aacff00 100644 --- a/fs/hfsplus/xattr_security.c +++ b/fs/hfsplus/xattr_security.c @@ -16,43 +16,17 @@ static int hfsplus_security_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size, int type) { - char *xattr_name; - int res; - - if (!strcmp(name, "")) - return -EINVAL; - - xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1, - GFP_KERNEL); - if (!xattr_name) - return -ENOMEM; - strcpy(xattr_name, XATTR_SECURITY_PREFIX); - strcpy(xattr_name + XATTR_SECURITY_PREFIX_LEN, name); - - res = hfsplus_getxattr(dentry, xattr_name, buffer, size); - kfree(xattr_name); - return res; + return hfsplus_getxattr(dentry, name, buffer, size, + XATTR_SECURITY_PREFIX, + XATTR_SECURITY_PREFIX_LEN); } static int hfsplus_security_setxattr(struct dentry *dentry, const char *name, const void *buffer, size_t size, int flags, int type) { - char *xattr_name; - int res; - - if (!strcmp(name, "")) - return -EINVAL; - - xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1, - GFP_KERNEL); - if (!xattr_name) - return -ENOMEM; - strcpy(xattr_name, XATTR_SECURITY_PREFIX); - strcpy(xattr_name + XATTR_SECURITY_PREFIX_LEN, name); - - res = hfsplus_setxattr(dentry, xattr_name, buffer, size, flags); - kfree(xattr_name); - return res; + return hfsplus_setxattr(dentry, name, buffer, size, flags, + XATTR_SECURITY_PREFIX, + XATTR_SECURITY_PREFIX_LEN); } static size_t hfsplus_security_listxattr(struct dentry *dentry, char *list, diff --git a/fs/hfsplus/xattr_trusted.c b/fs/hfsplus/xattr_trusted.c index 3c5f27e..bcf65089 100644 --- a/fs/hfsplus/xattr_trusted.c +++ b/fs/hfsplus/xattr_trusted.c @@ -14,43 +14,16 @@ static int hfsplus_trusted_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size, int type) { - char *xattr_name; - int res; - - if (!strcmp(name, "")) - return -EINVAL; - - xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1, - GFP_KERNEL); - if (!xattr_name) - return -ENOMEM; - strcpy(xattr_name, XATTR_TRUSTED_PREFIX); - strcpy(xattr_name + XATTR_TRUSTED_PREFIX_LEN, name); - - res = hfsplus_getxattr(dentry, xattr_name, buffer, size); - kfree(xattr_name); - return res; + return hfsplus_getxattr(dentry, name, buffer, size, + XATTR_TRUSTED_PREFIX, + XATTR_TRUSTED_PREFIX_LEN); } static int hfsplus_trusted_setxattr(struct dentry *dentry, const char *name, const void *buffer, size_t size, int flags, int type) { - char *xattr_name; - int res; - - if (!strcmp(name, "")) - return -EINVAL; - - xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1, - GFP_KERNEL); - if (!xattr_name) - return -ENOMEM; - strcpy(xattr_name, XATTR_TRUSTED_PREFIX); - strcpy(xattr_name + XATTR_TRUSTED_PREFIX_LEN, name); - - res = hfsplus_setxattr(dentry, xattr_name, buffer, size, flags); - kfree(xattr_name); - return res; + return hfsplus_setxattr(dentry, name, buffer, size, flags, + XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN); } static size_t hfsplus_trusted_listxattr(struct dentry *dentry, char *list, diff --git a/fs/hfsplus/xattr_user.c b/fs/hfsplus/xattr_user.c index 2b625a5..5aa0e6d 100644 --- a/fs/hfsplus/xattr_user.c +++ b/fs/hfsplus/xattr_user.c @@ -14,43 +14,16 @@ static int hfsplus_user_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size, int type) { - char *xattr_name; - int res; - if (!strcmp(name, "")) - return -EINVAL; - - xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1, - GFP_KERNEL); - if (!xattr_name) - return -ENOMEM; - strcpy(xattr_name, XATTR_USER_PREFIX); - strcpy(xattr_name + XATTR_USER_PREFIX_LEN, name); - - res = hfsplus_getxattr(dentry, xattr_name, buffer, size); - kfree(xattr_name); - return res; + return hfsplus_getxattr(dentry, name, buffer, size, + XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN); } static int hfsplus_user_setxattr(struct dentry *dentry, const char *name, const void *buffer, size_t size, int flags, int type) { - char *xattr_name; - int res; - - if (!strcmp(name, "")) - return -EINVAL; - - xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1, - GFP_KERNEL); - if (!xattr_name) - return -ENOMEM; - strcpy(xattr_name, XATTR_USER_PREFIX); - strcpy(xattr_name + XATTR_USER_PREFIX_LEN, name); - - res = hfsplus_setxattr(dentry, xattr_name, buffer, size, flags); - kfree(xattr_name); - return res; + return hfsplus_setxattr(dentry, name, buffer, size, flags, + XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN); } static size_t hfsplus_user_listxattr(struct dentry *dentry, char *list, |