OSDN Git Service

exportfs: fix 'passing zero to ERR_PTR()' warning
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / fs / xattr.c
index 072fee1..09441c3 100644 (file)
@@ -163,7 +163,7 @@ xattr_getsecurity(struct inode *inode, const char *name, void *value,
        }
        memcpy(value, buffer, len);
 out:
-       security_release_secctx(buffer, len);
+       kfree(buffer);
 out_noalloc:
        return len;
 }
@@ -442,7 +442,7 @@ getxattr(struct dentry *d, const char __user *name, void __user *value,
                        size = XATTR_SIZE_MAX;
                kvalue = kzalloc(size, GFP_KERNEL | __GFP_NOWARN);
                if (!kvalue) {
-                       vvalue = vmalloc(size);
+                       vvalue = vzalloc(size);
                        if (!vvalue)
                                return -ENOMEM;
                        kvalue = vvalue;
@@ -453,7 +453,7 @@ getxattr(struct dentry *d, const char __user *name, void __user *value,
        if (error > 0) {
                if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) ||
                    (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))
-                       posix_acl_fix_xattr_to_user(kvalue, size);
+                       posix_acl_fix_xattr_to_user(kvalue, error);
                if (size && copy_to_user(value, kvalue, error))
                        error = -EFAULT;
        } else if (error == -ERANGE && size >= XATTR_SIZE_MAX) {
@@ -720,7 +720,7 @@ generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t s
        handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
        if (!handler)
                return -EOPNOTSUPP;
-       return handler->get(dentry, name, buffer, size, handler->flags);
+       return handler->get(handler, dentry, name, buffer, size);
 }
 
 /*
@@ -735,15 +735,15 @@ generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
 
        if (!buffer) {
                for_each_xattr_handler(handlers, handler) {
-                       size += handler->list(dentry, NULL, 0, NULL, 0,
-                                             handler->flags);
+                       size += handler->list(handler, dentry, NULL, 0,
+                                             NULL, 0);
                }
        } else {
                char *buf = buffer;
 
                for_each_xattr_handler(handlers, handler) {
-                       size = handler->list(dentry, buf, buffer_size,
-                                            NULL, 0, handler->flags);
+                       size = handler->list(handler, dentry, buf, buffer_size,
+                                            NULL, 0);
                        if (size > buffer_size)
                                return -ERANGE;
                        buf += size;
@@ -767,7 +767,7 @@ generic_setxattr(struct dentry *dentry, const char *name, const void *value, siz
        handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
        if (!handler)
                return -EOPNOTSUPP;
-       return handler->set(dentry, name, value, size, flags, handler->flags);
+       return handler->set(handler, dentry, name, value, size, flags);
 }
 
 /*
@@ -782,8 +782,7 @@ generic_removexattr(struct dentry *dentry, const char *name)
        handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
        if (!handler)
                return -EOPNOTSUPP;
-       return handler->set(dentry, name, NULL, 0,
-                           XATTR_REPLACE, handler->flags);
+       return handler->set(handler, dentry, name, NULL, 0, XATTR_REPLACE);
 }
 
 EXPORT_SYMBOL(generic_getxattr);
@@ -791,6 +790,30 @@ EXPORT_SYMBOL(generic_listxattr);
 EXPORT_SYMBOL(generic_setxattr);
 EXPORT_SYMBOL(generic_removexattr);
 
+/**
+ * xattr_full_name  -  Compute full attribute name from suffix
+ *
+ * @handler:   handler of the xattr_handler operation
+ * @name:      name passed to the xattr_handler operation
+ *
+ * The get and set xattr handler operations are called with the remainder of
+ * the attribute name after skipping the handler's prefix: for example, "foo"
+ * is passed to the get operation of a handler with prefix "user." to get
+ * attribute "user.foo".  The full name is still "there" in the name though.
+ *
+ * Note: the list xattr handler operation when called from the vfs is passed a
+ * NULL name; some file systems use this operation internally, with varying
+ * semantics.
+ */
+const char *xattr_full_name(const struct xattr_handler *handler,
+                           const char *name)
+{
+       size_t prefix_len = strlen(handler->prefix);
+
+       return name - prefix_len;
+}
+EXPORT_SYMBOL(xattr_full_name);
+
 /*
  * Allocate new xattr and copy in the value; but leave the name to callers.
  */