anone_inode(匿名inode)


Rev.2を表示中。最新版はこちら

/tmp/file1は/tmpディレクトリから削除され、パスでの参照はできませんが、ファイル自体は存在し、a.outはfd1で参照し続けることが可能です。このようなファイルのinodeをanone inode(匿名inode)と言うようです。
#include <fcntl.h>
#include <stdio.h>

int main(void)
{
       int     err;

       int fd1 = open( "/tmp/file1", O_CREAT | O_RDWR, 0666 );
       int fd2 = open( "/tmp/file2", O_CREAT | O_RDWR, 0666 );
       err = unlink( "/tmp/file1" );
       printf("err:%d\n", err);
       while(1)
               sleep(1);
}

[root@localhost lkm]# ./a.out &
[1] 17342
err:0

[root@localhost lkm]# ls /tmp/file*
/tmp/file2

[root@localhost lkm]# ls -l /proc/17342/fd
合計 0
lrwx------ 1 root root 64  3月  7 15:29 0 -> /dev/pts/2
lrwx------ 1 root root 64  3月  7 15:29 1 -> /dev/pts/2
lrwx------ 1 root root 64  3月  7 15:29 2 -> /dev/pts/2
lrwx------ 1 root root 64  3月  7 15:29 3 -> /tmp/file1 (deleted)
lrwx------ 1 root root 64  3月  7 15:29 4 -> /tmp/file2
システムコールunlinkは、AT_FDCWDでdo_unlinkat()をコールします。AT_FDCWDはpathnameが相対パスの時プロセスのカレントパス(current->fs->pwd)から検索します。
SYSCALL_DEFINE1(unlink, const char __user *, pathname)
{
       return do_unlinkat(AT_FDCWD, pathname);
}
mnt_want_write()でunlinkするファイルのファイルシステムが書き込み可能ならmnt->mnt_writers++とし、そうでないなら削除できません。lookup_hash()でdentry取得のためdentry->d_count++すたのを、dput(dentry)でdentry->d_count--としてエラーです。

ファイルシステムが書き込み可能なら、vfs_unlink()で実ファイルおよびそのキャッシュの削除を行い、iput()でinode->i_count--とします。inode->i_count=0ならinodeキャッシュの削除も行いますが、そうでないならinodeキャッシュは存在することになり、anone inode(匿名inode)の誕生となります。
static long do_unlinkat(int dfd, const char __user *pathname)
{
       int error;
       char *name;
       struct dentry *dentry;
       struct nameidata nd;
       struct inode *inode = NULL;

       error = user_path_parent(dfd, pathname, &nd, &name);
       if (error)
               return error;

       error = -EISDIR;
       if (nd.last_type != LAST_NORM)
               goto exit1;

       nd.flags &= ~LOOKUP_PARENT;

       mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
       dentry = lookup_hash(&nd);
       error = PTR_ERR(dentry);
       if (!IS_ERR(dentry)) {
               if (nd.last.name[nd.last.len])
                       goto slashes;
               inode = dentry->d_inode;
               if (!inode)
                       goto slashes;
               ihold(inode);
               error = mnt_want_write(nd.path.mnt);
               if (error)
                       goto exit2;
               error = security_path_unlink(&nd.path, dentry);
               if (error)
                       goto exit3;
               error = vfs_unlink(nd.path.dentry->d_inode, dentry);
exit3:
               mnt_drop_write(nd.path.mnt);
       exit2:
               dput(dentry);
       }
       mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
       if (inode)
               iput(inode);    /* truncate the inode here */
exit1:
       path_put(&nd.path);
       putname(name);
       return error;

slashes:
       error = !dentry->d_inode ? -ENOENT :
               S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR;
       goto exit2;
}
削除するファイルのinodeコールバックのunlink()がコールされます。これはディレクトリのinodeのデータブロックから、このinodeを管理している設定を削除し、d_delete()でそのキャッシュも削除され、ファイルは階層的に管理されなくなりました。ただしunlink()コールバック関数は対象ファイルのinodeブロックは削除しません。
int vfs_unlink(struct inode *dir, struct dentry *dentry)
{
       int error = may_delete(dir, dentry, 0);

       if (error)
               return error;

       if (!dir->i_op->unlink)
               return -EPERM;

       mutex_lock(&dentry->d_inode->i_mutex);
       if (d_mountpoint(dentry))
               error = -EBUSY;
       else {
               error = security_inode_unlink(dir, dentry);
               if (!error) {
                       error = dir->i_op->unlink(dir, dentry);
                       if (!error)
                               dont_mount(dentry);
               }
       }
       mutex_unlock(&dentry->d_inode->i_mutex);

       if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) {
               fsnotify_link_count(dentry->d_inode);
               d_delete(dentry);
       }

       return error;
}


最終更新 2014/03/10 17:12:16 - north
(2014/03/10 17:00:19 作成)


検索

アクセス数
3023113
最近のコメント
list_head構造体 - yocto_no_yomikata
勧告ロックと強制ロック - wataash
LKMからのファイル出力 - 重松 宏昌
kprobe - ななし
ksetの実装 - スーパーコピー
カーネルスレッドとは - ノース
カーネルスレッドとは - nbyst
asmlinkageってなに? - ノース
asmlinkageってなに? - よろしく
はじめ - ノース
Adsense
広告情報が設定されていません。