Page MenuHomeFreeBSD

D55665.id173330.diff
No OneTemporary

D55665.id173330.diff

diff --git a/sys/fs/p9fs/p9fs.h b/sys/fs/p9fs/p9fs.h
--- a/sys/fs/p9fs/p9fs.h
+++ b/sys/fs/p9fs/p9fs.h
@@ -103,7 +103,7 @@
struct p9fs_inode inode; /* in memory representation of ondisk information*/
struct p9fs_session *p9fs_ses; /* Session_ptr for this node */
STAILQ_ENTRY(p9fs_node) p9fs_node_next;
- uint64_t flags;
+ u_int flags;
};
#define P9FS_VTON(vp) ((struct p9fs_node *)(vp)->v_data)
@@ -111,10 +111,13 @@
#define VFSTOP9(mp) ((struct p9fs_mount *)(mp)->mnt_data)
#define QEMU_DIRENTRY_SZ 25
#define P9FS_NODE_MODIFIED 0x1 /* indicating file change */
-#define P9FS_ROOT 0x2 /* indicating root p9fs node */
+#define P9FS_NODE_ROOT 0x2 /* indicating root p9fs node */
#define P9FS_NODE_DELETED 0x4 /* indicating file or directory delete */
#define P9FS_NODE_IN_SESSION 0x8 /* p9fs_node is in the session - virt_node_list */
-#define IS_ROOT(node) (node->flags & P9FS_ROOT)
+#define IS_ROOT(node) (((node)->flags & P9FS_NODE_ROOT) != 0)
+
+#define P9FS_NODE_SETF(n, f) atomic_set_int(&(n)->flags, (f))
+#define P9FS_NODE_CLRF(n, f) atomic_clear_int(&(n)->flags, (f))
#define P9FS_SET_LINKS(inode) do { \
(inode)->i_links_count = 1; \
diff --git a/sys/fs/p9fs/p9fs_vfsops.c b/sys/fs/p9fs/p9fs_vfsops.c
--- a/sys/fs/p9fs/p9fs_vfsops.c
+++ b/sys/fs/p9fs/p9fs_vfsops.c
@@ -284,7 +284,7 @@
node = vp->v_data;
/* Remove stale vnode from hash list */
vfs_hash_remove(vp);
- node->flags |= P9FS_NODE_DELETED;
+ P9FS_NODE_SETF(node, P9FS_NODE_DELETED);
vput(vp);
*vpp = NULL;
@@ -372,7 +372,7 @@
if (*vpp == NULL) {
P9FS_LOCK(vses);
STAILQ_INSERT_TAIL(&vses->virt_node_list, np, p9fs_node_next);
- np->flags |= P9FS_NODE_IN_SESSION;
+ P9FS_NODE_SETF(np, P9FS_NODE_IN_SESSION);
P9FS_UNLOCK(vses);
vn_set_state(vp, VSTATE_CONSTRUCTED);
*vpp = vp;
@@ -448,7 +448,7 @@
P9FS_VOFID_LOCK_INIT(p9fs_root);
STAILQ_INIT(&p9fs_root->vofid_list);
p9fs_root->parent = p9fs_root;
- p9fs_root->flags |= P9FS_ROOT;
+ P9FS_NODE_SETF(p9fs_root, P9FS_NODE_ROOT);
p9fs_root->p9fs_ses = vses;
vfs_getnewfsid(mp);
strlcpy(mp->mnt_stat.f_mntfromname, from,
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
@@ -111,7 +111,7 @@
P9FS_LOCK(vses);
if ((np->flags & P9FS_NODE_IN_SESSION) != 0) {
- np->flags &= ~P9FS_NODE_IN_SESSION;
+ P9FS_NODE_CLRF(np, P9FS_NODE_IN_SESSION);
STAILQ_REMOVE(&vses->virt_node_list, np, p9fs_node, p9fs_node_next);
} else {
P9FS_UNLOCK(vses);
@@ -675,7 +675,7 @@
error = vinvalbuf(vp, 0, 0, 0);
if (error != 0)
return (error);
- np->flags &= ~P9FS_NODE_MODIFIED;
+ P9FS_NODE_CLRF(np, P9FS_NODE_MODIFIED);
}
vfid = p9fs_get_fid(vses->clnt, np, ap->a_cred, VFID, -1, &error);
@@ -896,6 +896,7 @@
/* Basic info */
VATTR_NULL(vap);
+ VI_LOCK(vp);
vap->va_atime.tv_sec = inode->i_atime;
vap->va_mtime.tv_sec = inode->i_mtime;
vap->va_ctime.tv_sec = inode->i_ctime;
@@ -916,6 +917,7 @@
vap->va_filerev = inode->data_version;
vap->va_vaflags = 0;
vap->va_bytes = inode->blocks * P9PROTO_TGETATTR_BLK;
+ VI_UNLOCK(vp);
return (0);
}
@@ -951,16 +953,36 @@
{
struct p9fs_node *np;
struct p9fs_inode *inode;
+ bool excl_locked;
np = P9FS_VTON(vp);
inode = &np->inode;
+ /*
+ * This function might be called with the vnode only shared
+ * locked. Then, interlock the vnode to ensure the exclusive
+ * access to the inode fields: the thread either owns
+ * exclusive vnode lock, or shared vnode lock plus interlock.
+ *
+ * If the vnode is locked exclusive, do not take the
+ * interlock. We directly call vnode_pager_setsize(), which
+ * needs the vm_object lock, and that lock is before vnode
+ * interlock in the lock order.
+ */
ASSERT_VOP_LOCKED(vp, __func__);
+ excl_locked = VOP_ISLOCKED(vp) == LK_EXCLUSIVE;
+ if (!excl_locked)
+ VI_LOCK(vp);
+
/* Update the pager size if file size changes on host */
if (inode->i_size != stat->st_size) {
inode->i_size = stat->st_size;
- if (vp->v_type == VREG)
- vnode_pager_setsize(vp, inode->i_size);
+ if (vp->v_type == VREG) {
+ if (excl_locked)
+ vnode_pager_setsize(vp, inode->i_size);
+ else
+ vn_delayed_setsize_locked(vp);
+ }
}
inode->i_mtime = stat->st_mtime_sec;
@@ -979,11 +1001,12 @@
inode->gen = stat->st_gen;
inode->data_version = stat->st_data_version;
- ASSERT_VOP_LOCKED(vp, __func__);
/* Setting a flag if file changes based on qid version */
if (np->vqid.qid_version != stat->qid.version)
- np->flags |= P9FS_NODE_MODIFIED;
+ P9FS_NODE_SETF(np, P9FS_NODE_MODIFIED);
memcpy(&np->vqid, &stat->qid, sizeof(stat->qid));
+ if (!excl_locked)
+ VI_UNLOCK(vp);
return (0);
}
@@ -1526,7 +1549,7 @@
cache_purge(vp);
vfs_hash_remove(vp);
- np->flags |= P9FS_NODE_DELETED;
+ P9FS_NODE_SETF(np, P9FS_NODE_DELETED);
return (error);
}
@@ -2213,12 +2236,25 @@
return (rtvals[0]);
}
+static int
+p9fs_delayed_setsize(struct vop_delayed_setsize_args *ap)
+{
+ struct vnode *vp;
+ struct p9fs_node *np;
+
+ vp = ap->a_vp;
+ np = P9FS_VTON(vp);
+ vnode_pager_setsize(vp, np->inode.i_size);
+ return (0);
+}
+
struct vop_vector p9fs_vnops = {
.vop_default = &default_vnodeops,
.vop_lookup = p9fs_lookup,
.vop_open = p9fs_open,
.vop_close = p9fs_close,
.vop_access = p9fs_access,
+ .vop_delayed_setsize = p9fs_delayed_setsize,
.vop_getattr = p9fs_getattr_dotl,
.vop_setattr = p9fs_setattr_dotl,
.vop_reclaim = p9fs_reclaim,

File Metadata

Mime Type
text/plain
Expires
Sun, Apr 26, 6:45 AM (3 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
32170663
Default Alt Text
D55665.id173330.diff (5 KB)

Event Timeline