Page MenuHomeFreeBSD

D47438.diff
No OneTemporary

D47438.diff

diff --git a/sys/fs/p9fs/p9_client.h b/sys/fs/p9fs/p9_client.h
--- a/sys/fs/p9fs/p9_client.h
+++ b/sys/fs/p9fs/p9_client.h
@@ -140,6 +140,7 @@
int p9_client_file_create(struct p9_fid *fid, char *name, uint32_t perm, int mode,
char *extension);
int p9_client_remove(struct p9_fid *fid);
+int p9_client_unlink(struct p9_fid *dfid, const char *name, int32_t flags);
int p9_dirent_read(struct p9_client *clnt, char *buf, int start, int len,
struct p9_dirent *dirent);
int p9_client_statfs(struct p9_fid *fid, struct p9_statfs *stat);
diff --git a/sys/fs/p9fs/p9_client.c b/sys/fs/p9fs/p9_client.c
--- a/sys/fs/p9fs/p9_client.c
+++ b/sys/fs/p9fs/p9_client.c
@@ -669,6 +669,27 @@
return (error);
}
+int
+p9_client_unlink(struct p9_fid *dfid, const char *name, int32_t flags)
+{
+ int error;
+ struct p9_client *clnt;
+ struct p9_req_t *req;
+
+ error = 0;
+ clnt = dfid->clnt;
+
+ req = p9_client_request(clnt, P9PROTO_TUNLINKAT, &error, "dsd",
+ dfid->fid, name, flags);
+ if (error != 0) {
+ P9_DEBUG(PROTO, "RUNLINKAT fid %d\n", dfid->fid);
+ return (error);
+ }
+
+ p9_free_req(clnt, req);
+ return (error);
+}
+
/* Inform the file server that the current file represented by fid is no longer
* needed by the client. Any allocated fid on the server needs a clunk to be
* destroyed.
diff --git a/sys/fs/p9fs/p9_protocol.h b/sys/fs/p9fs/p9_protocol.h
--- a/sys/fs/p9fs/p9_protocol.h
+++ b/sys/fs/p9fs/p9_protocol.h
@@ -267,6 +267,8 @@
#define P9PROTO_TGETATTR_BLK 512
+#define P9PROTO_UNLINKAT_REMOVEDIR 0x200
+
/* PDU buffer used for SG lists. */
struct p9_buffer {
uint32_t size;
diff --git a/sys/fs/p9fs/p9fs_vnops.c b/sys/fs/p9fs/p9fs_vnops.c
--- a/sys/fs/p9fs/p9fs_vnops.c
+++ b/sys/fs/p9fs/p9fs_vnops.c
@@ -1497,7 +1497,8 @@
* After that, does a node metadata cleanup on client side.
*/
static int
-remove_common(struct p9fs_node *np, struct ucred *cred)
+remove_common(struct p9fs_node *dnp, struct p9fs_node *np, const char *name,
+ struct ucred *cred)
{
int error;
struct p9fs_session *vses;
@@ -1508,21 +1509,23 @@
vses = np->p9fs_ses;
vp = P9FS_NTOV(np);
- vfid = p9fs_get_fid(vses->clnt, np, cred, VFID, -1, &error);
+ vfid = p9fs_get_fid(vses->clnt, dnp, cred, VFID, -1, &error);
if (error != 0)
return (error);
- error = p9_client_remove(vfid);
+ error = p9_client_unlink(vfid, name,
+ np->v_node->v_type == VDIR ? P9PROTO_UNLINKAT_REMOVEDIR : 0);
if (error != 0)
return (error);
/* Remove all non-open fids associated with the vp */
- p9fs_fid_remove_all(np, TRUE);
+ if (np->inode.i_links_count == 1)
+ p9fs_fid_remove_all(np, TRUE);
/* Invalidate all entries of vnode from name cache and hash list. */
cache_purge(vp);
-
vfs_hash_remove(vp);
+
np->flags |= P9FS_NODE_DELETED;
return (error);
@@ -1537,8 +1540,10 @@
struct vnode *dvp;
struct p9fs_node *dnp;
struct p9fs_inode *dinode;
+ struct componentname *cnp;
int error;
+ cnp = ap->a_cnp;
vp = ap->a_vp;
np = P9FS_VTON(vp);
dvp = ap->a_dvp;
@@ -1550,7 +1555,7 @@
if (vp->v_type == VDIR)
return (EISDIR);
- error = remove_common(np, ap->a_cnp->cn_cred);
+ error = remove_common(dnp, np, cnp->cn_nameptr, cnp->cn_cred);
if (error == 0)
P9FS_DECR_LINKS(dinode);
@@ -1566,8 +1571,10 @@
struct vnode *dvp;
struct p9fs_node *dnp;
struct p9fs_inode *dinode;
+ struct componentname *cnp;
int error;
+ cnp = ap->a_cnp;
vp = ap->a_vp;
np = P9FS_VTON(vp);
dvp = ap->a_dvp;
@@ -1576,7 +1583,7 @@
P9_DEBUG(VOPS, "%s: vp %p node %p \n", __func__, vp, np);
- error = remove_common(np, ap->a_cnp->cn_cred);
+ error = remove_common(dnp, np, cnp->cn_nameptr, cnp->cn_cred);
if (error == 0)
P9FS_DECR_LINKS(dinode);

File Metadata

Mime Type
text/plain
Expires
Sat, Jan 25, 2:34 PM (17 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16148088
Default Alt Text
D47438.diff (3 KB)

Event Timeline