Skip to content

Commit 7752518

Browse files
author
Daniel Herald
committed
Only drop inode resources if refcount drops to 0.
1 parent ed742a6 commit 7752518

File tree

4 files changed

+47
-29
lines changed

4 files changed

+47
-29
lines changed

vvsfs/dir.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
#include <linux/types.h>
1515
#include <linux/version.h>
1616

17-
#include "vvsfs.h"
1817
#include "logging.h"
18+
#include "vvsfs.h"
1919

2020
// vvsfs_readdir - reads a directory and places the result using filldir, cached
2121
// in dcache

vvsfs/inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
#include <linux/types.h>
1515
#include <linux/version.h>
1616

17-
#include "vvsfs.h"
1817
#include "logging.h"
18+
#include "vvsfs.h"
1919

2020
struct inode *vvsfs_iget(struct super_block *sb, unsigned long ino);
2121

vvsfs/namei.c

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
#include <linux/types.h>
1515
#include <linux/version.h>
1616

17-
#include "vvsfs.h"
1817
#include "logging.h"
18+
#include "vvsfs.h"
1919

2020
struct inode *vvsfs_iget(struct super_block *sb, unsigned long ino);
2121

@@ -215,9 +215,9 @@ static int vvsfs_find_entry_indirect(struct vvsfs_inode_info *vi,
215215
* otherwise and error
216216
*/
217217
int vvsfs_find_entry(struct inode *dir,
218-
struct dentry *dentry,
219-
unsigned flags,
220-
struct bufloc_t *out_loc) {
218+
struct dentry *dentry,
219+
unsigned flags,
220+
struct bufloc_t *out_loc) {
221221
struct vvsfs_inode_info *vi;
222222
struct super_block *sb;
223223
int result;
@@ -670,6 +670,13 @@ int vvsfs_free_inode_blocks(struct inode *inode) {
670670

671671
DEBUG_LOG("vvsfs - free inode blocks - %lu", inode->i_ino);
672672

673+
if (inode->i_nlink != 0) {
674+
DEBUG_LOG(
675+
"vvsfs - free inode blocks called on allocated inode (links %u)",
676+
inode->i_nlink);
677+
return -EIO;
678+
}
679+
673680
vi = VVSFS_I(inode);
674681
sb = inode->i_sb;
675682
i_sb = sb->s_fs_info;
@@ -699,6 +706,21 @@ int vvsfs_free_inode_blocks(struct inode *inode) {
699706
return 0;
700707
}
701708

709+
/* Drops the link count of a given inode and frees the resources if applicable
710+
*
711+
* @inode: Target inode to drop link count of
712+
*
713+
* @return: (int) 0 if successful, error otherwise
714+
*/
715+
int vvsfs_drop_inode_link(struct inode *inode) {
716+
DEBUG_LOG("vvsfs - drop inode link");
717+
inode_dec_link_count(inode);
718+
if (inode->i_nlink == 0) {
719+
return vvsfs_free_inode_blocks(inode);
720+
}
721+
return 0;
722+
}
723+
702724
/* Calculate the data block map index for a given position
703725
* within the given inode data blocks.
704726
*
@@ -1079,7 +1101,7 @@ vvsfs_create(struct mnt_idmap *namespace,
10791101
if (ret != 0) {
10801102
DEBUG_LOG("vvsfs - create - failed to create new entry for intial data "
10811103
"block\n");
1082-
vvsfs_free_inode_blocks(inode);
1104+
vvsfs_drop_inode_link(inode);
10831105
discard_new_inode(inode);
10841106
return ret;
10851107
}
@@ -1360,16 +1382,15 @@ static int vvsfs_unlink(struct inode *dir, struct dentry *dentry) {
13601382
"entry\n");
13611383
return err;
13621384
}
1363-
err = vvsfs_free_inode_blocks(inode);
1385+
1386+
inode->i_ctime = dir->i_ctime;
1387+
1388+
err = vvsfs_drop_inode_link(inode);
13641389
if (err) {
13651390
DEBUG_LOG("vvsfs - unlink - failed to free inode blocks\n");
13661391
return err;
13671392
}
1368-
inode->i_ctime = dir->i_ctime;
1369-
DEBUG_LOG("vvsfs - unlink - link count before: %u\n", inode->i_nlink);
1370-
inode_dec_link_count(inode);
1371-
DEBUG_LOG("vvsfs - unlink - link count after: %u\n", inode->i_nlink);
1372-
mark_inode_dirty(inode);
1393+
13731394
DEBUG_LOG("vvsfs - unlink - done\n");
13741395
return err;
13751396
}
@@ -1508,7 +1529,6 @@ vvsfs_symlink(struct mnt_idmap *namespace,
15081529
struct dentry *dentry,
15091530
const char *symname) {
15101531
struct vvsfs_inode_info *dir_info;
1511-
int ret;
15121532
int err;
15131533
struct buffer_head *bh;
15141534
struct inode *inode;
@@ -1536,18 +1556,18 @@ vvsfs_symlink(struct mnt_idmap *namespace,
15361556

15371557
err = page_symlink(inode, symname, strlen(symname) + 1);
15381558
if (err) {
1539-
vvsfs_free_inode_blocks(inode);
1559+
vvsfs_drop_inode_link(inode);
15401560
discard_new_inode(inode);
15411561
return err;
15421562
}
15431563

15441564
// add the file/directory to the parent directory's list
15451565
// of entries -- on disk.
1546-
ret = vvsfs_add_new_entry(dir, dentry, inode);
1547-
if (ret != 0) {
1548-
vvsfs_free_inode_blocks(inode);
1566+
err = vvsfs_add_new_entry(dir, dentry, inode);
1567+
if (err != 0) {
1568+
vvsfs_drop_inode_link(inode);
15491569
discard_new_inode(inode);
1550-
return ret;
1570+
return err;
15511571
}
15521572

15531573
d_instantiate(dentry, inode);
@@ -1599,7 +1619,7 @@ static int vvsfs_mknod(struct user_namespace *mnt_userns,
15991619
// of entries -- on disk.
16001620
ret = vvsfs_add_new_entry(dir, dentry, inode);
16011621
if (ret != 0) {
1602-
vvsfs_free_inode_blocks(inode);
1622+
vvsfs_drop_inode_link(inode);
16031623
discard_new_inode(inode);
16041624
return ret;
16051625
}
@@ -1650,15 +1670,13 @@ static int vvsfs_dentry_exchange_inode(struct inode *dir,
16501670
dir->i_mtime = dir->i_ctime = current_time(dir);
16511671
mark_inode_dirty(dir);
16521672

1653-
// Drop the link count of the inode that was originally pointed to by this
1654-
// dentry, so that it can possibly be deleted
1673+
// Update inode create time
16551674
existing_inode->i_ctime = current_time(existing_inode);
1656-
DEBUG_LOG("vvsfs - rename - new_inode link count before: %u\n",
1657-
existing_inode->i_nlink);
1658-
inode_dec_link_count(existing_inode);
1659-
DEBUG_LOG("vvsfs - rename - new_inode link count after: %u\n",
1660-
existing_inode->i_nlink);
1661-
mark_inode_dirty(existing_inode);
1675+
1676+
// Drop the link count of the inode that was originally pointed to by this
1677+
// dentry
1678+
vvsfs_drop_inode_link(existing_inode);
1679+
16621680
return 0;
16631681
}
16641682

vvsfs/vvsfs_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
* bitmaps, and using address space operations to simplify read/write.
88
*/
99

10-
#include "vvsfs.h"
1110
#include "logging.h"
11+
#include "vvsfs.h"
1212

1313
// inode cache -- this is used to attach vvsfs specific inode
1414
// data to the vfs inode

0 commit comments

Comments
 (0)