unfuck nfs patch
This commit is contained in:
parent
14137b2552
commit
b070b5da8d
2 changed files with 195 additions and 0 deletions
|
@ -46,6 +46,10 @@ in
|
|||
hash = "sha256-SpKDm4PXR6qs7kX5SGVpFF/EPBijMhX1NsFUHrlCynM=";
|
||||
};
|
||||
}
|
||||
{
|
||||
name = "nfs-unfuck.patch";
|
||||
patch = ./nfs-unfuck.patch;
|
||||
}
|
||||
];
|
||||
|
||||
structuredExtraConfig = with lib.kernel; {
|
||||
|
|
191
linux/vf2/nfs-unfuck.patch
Normal file
191
linux/vf2/nfs-unfuck.patch
Normal file
|
@ -0,0 +1,191 @@
|
|||
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
|
||||
index d3665390c4cb..7a782a1717d3 100644
|
||||
--- a/fs/nfs/nfs4proc.c
|
||||
+++ b/fs/nfs/nfs4proc.c
|
||||
@@ -55,6 +55,7 @@
|
||||
#include <linux/utsname.h>
|
||||
#include <linux/freezer.h>
|
||||
#include <linux/iversion.h>
|
||||
+#include <linux/posix_acl_xattr.h>
|
||||
|
||||
#include "nfs4_fs.h"
|
||||
#include "delegation.h"
|
||||
@@ -327,7 +328,7 @@ static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dent
|
||||
memset(&readdir->verifier, 0, sizeof(readdir->verifier));
|
||||
if (cookie == 2)
|
||||
return;
|
||||
-
|
||||
+
|
||||
/*
|
||||
* NFSv4 servers do not return entries for '.' and '..'
|
||||
* Therefore, we fake these entries here. We let '.'
|
||||
@@ -336,7 +337,7 @@ static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dent
|
||||
* instead of 1 or 2.
|
||||
*/
|
||||
start = p = kmap_atomic(*readdir->pages);
|
||||
-
|
||||
+
|
||||
if (cookie == 0) {
|
||||
*p++ = xdr_one; /* next */
|
||||
*p++ = xdr_zero; /* cookie, first word */
|
||||
@@ -350,7 +351,7 @@ static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dent
|
||||
*p++ = htonl(NF4DIR);
|
||||
p = xdr_encode_hyper(p, NFS_FILEID(d_inode(dentry)));
|
||||
}
|
||||
-
|
||||
+
|
||||
*p++ = xdr_one; /* next */
|
||||
*p++ = xdr_zero; /* cookie, first word */
|
||||
*p++ = xdr_two; /* cookie, second word */
|
||||
@@ -2147,7 +2148,7 @@ static int nfs4_open_recover_helper(struct nfs4_opendata *opendata,
|
||||
nfs4_init_opendata_res(opendata);
|
||||
ret = _nfs4_recover_proc_open(opendata);
|
||||
if (ret != 0)
|
||||
- return ret;
|
||||
+ return ret;
|
||||
newstate = nfs4_opendata_to_nfs4_state(opendata);
|
||||
if (IS_ERR(newstate))
|
||||
return PTR_ERR(newstate);
|
||||
@@ -3709,13 +3710,13 @@ static const struct rpc_call_ops nfs4_close_ops = {
|
||||
.rpc_release = nfs4_free_closedata,
|
||||
};
|
||||
|
||||
-/*
|
||||
- * It is possible for data to be read/written from a mem-mapped file
|
||||
+/*
|
||||
+ * It is possible for data to be read/written from a mem-mapped file
|
||||
* after the sys_close call (which hits the vfs layer as a flush).
|
||||
- * This means that we can't safely call nfsv4 close on a file until
|
||||
+ * This means that we can't safely call nfsv4 close on a file until
|
||||
* the inode is cleared. This in turn means that we are not good
|
||||
- * NFSv4 citizens - we do not indicate to the server to update the file's
|
||||
- * share state even when we are done with one of the three share
|
||||
+ * NFSv4 citizens - we do not indicate to the server to update the file's
|
||||
+ * share state even when we are done with one of the three share
|
||||
* stateid's in the inode.
|
||||
*
|
||||
* NOTE: Caller must be holding the sp->so_owner semaphore!
|
||||
@@ -4335,7 +4336,7 @@ int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
|
||||
return err;
|
||||
}
|
||||
|
||||
-/*
|
||||
+/*
|
||||
* The file is not closed if it is opened due to the a request to change
|
||||
* the size of the file. The open call will not be needed once the
|
||||
* VFS layer lookup-intents are implemented.
|
||||
@@ -4367,7 +4368,7 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
|
||||
pnfs_commit_and_return_layout(inode);
|
||||
|
||||
nfs_fattr_init(fattr);
|
||||
-
|
||||
+
|
||||
/* Deal with open(O_TRUNC) */
|
||||
if (sattr->ia_valid & ATTR_OPEN)
|
||||
sattr->ia_valid &= ~(ATTR_MTIME|ATTR_CTIME);
|
||||
@@ -5024,7 +5025,7 @@ static int _nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
|
||||
data->arg.u.symlink.pages = &page;
|
||||
data->arg.u.symlink.len = len;
|
||||
data->arg.label = label;
|
||||
-
|
||||
+
|
||||
status = nfs4_do_create(dir, dentry, data);
|
||||
|
||||
nfs4_free_createdata(data);
|
||||
@@ -10623,6 +10624,78 @@ static void nfs4_disable_swap(struct inode *inode)
|
||||
nfs4_schedule_state_manager(clp);
|
||||
}
|
||||
|
||||
+static struct posix_acl *nfs4_get_acl(struct mnt_idmap *idmap,
|
||||
+ struct dentry *dentry, int type) {int size;
|
||||
+ const char *name;
|
||||
+ char *value = NULL;
|
||||
+ struct posix_acl *acl;
|
||||
+ struct inode* inode = d_inode(dentry);
|
||||
+
|
||||
+ switch (type) {
|
||||
+ case ACL_TYPE_ACCESS:
|
||||
+ name = XATTR_USER_PREFIX XATTR_POSIX_ACL_ACCESS;
|
||||
+ break;
|
||||
+ case ACL_TYPE_DEFAULT:
|
||||
+ name = XATTR_USER_PREFIX XATTR_POSIX_ACL_DEFAULT;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+ }
|
||||
+
|
||||
+ size = nfs4_xattr_get_nfs4_user(NULL, dentry, inode, name, NULL, 0);
|
||||
+ if (size > 0) {
|
||||
+ value = kzalloc(size, GFP_KERNEL);
|
||||
+ if (!value)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+ size = nfs4_xattr_get_nfs4_user(NULL, dentry, inode, name, value, size);
|
||||
+ }
|
||||
+ if (size > 0)
|
||||
+ acl = posix_acl_from_xattr(&init_user_ns, value, size);
|
||||
+ else if (size == -ENODATA || size == 0)
|
||||
+ acl = NULL;
|
||||
+ else
|
||||
+ acl = ERR_PTR(size);
|
||||
+ kfree(value);
|
||||
+
|
||||
+ return acl;
|
||||
+}
|
||||
+
|
||||
+static int nfs4_set_acl(struct mnt_idmap *idmap,
|
||||
+ struct dentry *dentry, struct posix_acl *acl,
|
||||
+ int type)
|
||||
+{
|
||||
+ int rc = 0;
|
||||
+ char * name = NULL;
|
||||
+ void * value = NULL;
|
||||
+ int size = 0;
|
||||
+ struct inode* inode = d_inode(dentry);
|
||||
+
|
||||
+ switch (type) {
|
||||
+ case ACL_TYPE_ACCESS:
|
||||
+ name = XATTR_USER_PREFIX XATTR_POSIX_ACL_ACCESS;
|
||||
+ break;
|
||||
+ case ACL_TYPE_DEFAULT:
|
||||
+ name = XATTR_USER_PREFIX XATTR_POSIX_ACL_DEFAULT;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ size = posix_acl_to_xattr(&init_user_ns, acl, NULL, 0);
|
||||
+
|
||||
+ value = kzalloc(size, GFP_KERNEL);
|
||||
+
|
||||
+ if(!value)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ rc = nfs4_xattr_set_nfs4_user(NULL, idmap, dentry, inode, name, value, size, 0);
|
||||
+
|
||||
+ kfree(value);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+
|
||||
static const struct inode_operations nfs4_dir_inode_operations = {
|
||||
.create = nfs_create,
|
||||
.lookup = nfs_lookup,
|
||||
@@ -10638,6 +10711,8 @@ static const struct inode_operations nfs4_dir_inode_operations = {
|
||||
.getattr = nfs_getattr,
|
||||
.setattr = nfs_setattr,
|
||||
.listxattr = nfs4_listxattr,
|
||||
+ .get_acl = nfs4_get_acl,
|
||||
+ .set_acl = nfs4_set_acl,
|
||||
};
|
||||
|
||||
static const struct inode_operations nfs4_file_inode_operations = {
|
||||
@@ -10645,6 +10720,8 @@ static const struct inode_operations nfs4_file_inode_operations = {
|
||||
.getattr = nfs_getattr,
|
||||
.setattr = nfs_setattr,
|
||||
.listxattr = nfs4_listxattr,
|
||||
+ .get_acl = nfs4_get_acl,
|
||||
+ .set_acl = nfs4_set_acl,
|
||||
};
|
||||
|
||||
const struct nfs_rpc_ops nfs_v4_clientops = {
|
Reference in a new issue