IBM / LTFS-Data-Management

Apache License 2.0
27 stars 10 forks source link

number of links in stat information not correctly updated #8

Open martin-petermann opened 6 years ago

martin-petermann commented 6 years ago

From @martin-petermann on April 24, 2018 11:58

If I run the following program:

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

#include <iostream>
#include <sstream>

void print_nlink(std::string fname)

{
    struct stat statbuf;

    if ( stat(fname.c_str(), &statbuf) != -1 )
        std::cout << "number of links for file " << fname << ": " << statbuf.st_nlink << std::endl;
    else
        std::cout << "error detemining the number of links for file " << fname << ", errno: "<< errno << std::endl;
}

std::string mkname(std::string fname, int i)

{
    std::stringstream sname;

    sname << fname << "." << i;

    return sname.str();
}

void mklink(std::string fname, int i, int j)

{
    std::stringstream lnk1;
    std::stringstream lnk2;

    if ( link(mkname(fname, i).c_str(), mkname(fname, j).c_str()) == -1 ) {
        std::cout << "error creating link for file " << fname << ", errno: " << errno << std::endl;
        return;
    }
}

int main(int argc, char **argv)

{
    std::string fname;

    if ( argc != 2 ) {
        std::cout << "usage " << argv[0] << " <file name 1>" << std::endl;
        return 0;
    }

    fname = argv[1];

    std::cout << "create a file" << mkname(fname,0) << std::endl;

    if (mknod(mkname(fname,0).c_str(), 644, S_IFREG) == 1) {
        std::cout << "mknod error: " << strerror(errno) << std::endl;
    }

    print_nlink(mkname(fname,0));
    std::cout << std::endl;

    std::cout << "create one link " << mkname(fname,1) << std::endl;
    mklink(fname, 0, 1);

    print_nlink(mkname(fname,0));
    print_nlink(mkname(fname,1));
    std::cout << std::endl;

    std::cout << "create one additional link " << mkname(fname,2) << std::endl;
    mklink(fname, 1, 2);

    print_nlink(mkname(fname,0));
    print_nlink(mkname(fname,1));
    print_nlink(mkname(fname,2));
    std::cout << std::endl;

    sleep(1);

    std::cout << "wait for second" << std::endl;
    print_nlink(mkname(fname,0));
    print_nlink(mkname(fname,1));
    print_nlink(mkname(fname,2));

    return 0;
}

the output is the following:

[root@visp links]# /home/martin/C/link file
create a filefile.0
number of links for file file.0: 1

create one link file.1
number of links for file file.0: 2
number of links for file file.1: 2

create one additional link file.2
number of links for file file.0: 2         # needs to be '3'
number of links for file file.1: 3
number of links for file file.2: 3

wait for second
number of links for file file.0: 3
number of links for file file.1: 3
number of links for file file.2: 3

The number of links of the "original" file is immediately not correctly updated after creating link "file.2".

Choosing the Fuse option "attr_timeout=0" resolves the issue but leads to a bad performance.

Copied from original issue: martin-petermann/LTFS-Data-Management#8