static int au_hfsn_alloc(struct au_hinode *hinode) { struct au_hnotify *hn; struct super_block *sb; struct au_branch *br; struct fsnotify_mark *mark; aufs_bindex_t bindex; hn = hinode->hi_notify; sb = hn->hn_aufs_inode->i_sb; bindex = au_br_index(sb, hinode->hi_id); br = au_sbr(sb, bindex); mark = &hn->hn_mark; fsnotify_init_mark(mark, au_hfsn_free_mark); mark->mask = AuHfsnMask; /* * by udba rename or rmdir, aufs assign a new inode to the known * h_inode, so specify 1 to allow dups. */ return fsnotify_add_mark(mark, br->br_hfsn_group, hinode->hi_inode, /*mnt*/NULL, /*allow_dups*/1); }
struct audit_fsnotify_mark *audit_alloc_mark(struct audit_krule *krule, char *pathname, int len) { struct audit_fsnotify_mark *audit_mark; struct path path; struct dentry *dentry; struct inode *inode; int ret; if (pathname[0] != '/' || pathname[len-1] == '/') return ERR_PTR(-EINVAL); dentry = kern_path_locked(pathname, &path); if (IS_ERR(dentry)) return (void *)dentry; /* returning an error */ inode = path.dentry->d_inode; inode_unlock(inode); audit_mark = kzalloc(sizeof(*audit_mark), GFP_KERNEL); if (unlikely(!audit_mark)) { audit_mark = ERR_PTR(-ENOMEM); goto out; } fsnotify_init_mark(&audit_mark->mark, audit_fsnotify_free_mark); audit_mark->mark.mask = AUDIT_FS_EVENTS; audit_mark->path = pathname; audit_update_mark(audit_mark, dentry->d_inode); audit_mark->rule = krule; ret = fsnotify_add_mark(&audit_mark->mark, audit_fsnotify_group, inode, NULL, true); if (ret < 0) { audit_fsnotify_mark_free(audit_mark); audit_mark = ERR_PTR(ret); } out: dput(dentry); path_put(&path); return audit_mark; }