On Linux, can a symbolic link value be greater than PATH_MAX?

As every child in kindergarten knows, the file path on Linux cannot be longer than characters PATH_MAX.

But experimenting on my system, the team

ln -s $(for i in {0..1024}; do printf dir/../; done)foobar foobar1

fails with an error message File name too long.

I don’t quite understand why. There is no long file name, this is a very simple file content foobar1. No one has yet tried to cross the contents of a symbolic link to get to the goal. Of course, I may have a file whose contents are much larger PATH_MAX.

On the other hand, a team like

for i in {0..4096}; do ln -s $i $(expr $i + 1); done

succeeds. Only if I tried to cross the chain does the system complain.

. , ( ), , .

Linux, ? ?

+4
1

symlink

ENAMETOOLONG (File name too long)

. , SYMLINK_MAX . ...

XFS

if (pathlen < 0 || pathlen > MAXPATHLEN) {
  xfs_alert(mp, "%s: inode (%llu) bad symlink length (%lld)",
  __func__, (unsigned long long) ip->i_ino,
  .......
}

MAXPATHLEN == 1024

ReiserFS

item_len = ROUND_UP(strlen(symname));
if (item_len > MAX_DIRECT_ITEM_LEN(parent_dir->i_sb->s_blocksize)) {
  retval = -ENAMETOOLONG;
  .......
}

ext2

struct super_block * sb = dir->i_sb;
int err = -ENAMETOOLONG;
unsigned l = strlen(symname)+1;
.....
if (l > sb->s_blocksize)
   goto out;
....
return err;

, , , , PATH_MAX, , . symlink Linux.

ENAMETOOLONG
    target or linkpath was too long.

, . , , - _POSIX_SYMLINK_MAX.

#define _POSIX_SYMLINK_MAX  255 

, .

ln -s foo Fh5LNDZYm2vUlf3jypJtAaX1ElqHZAF4ivsuq8sHyKVLDrYi4zR3T2QcXwS5TPRTys9aUxuh3qtnlNnFQGInmLiM7GK1xpN78ZbcD4JWizfPa7VWwhR4XWpvaJLHCIONUTC6A8fjNVfhv434vWckuKDzTacno0LE13mBVHuj5RDgJIkmW1zUcMMh5E38VisPxSN7BGxBVXHtn0cUPmZLmYSzGrOJqEJzimvwh2uDi8uXEOwBLbsfYlxBOz1kw8P

ln -s foo Fh5LNDZYm2vUlf3jypJtAaX1ElqHZAF4ivsuq8sHyKVLDrYi4zR3T2QcXwS5TPRTys9aUxuh3qtnlNnFQGInmLiM7GK1xpN78ZbcD4JWizfPa7VWwhR4XWpvaJLHCIONUTC6A8fjNVfhv434vWckuKDzTacno0LE13mBVHuj5RDgJIkmW1zUcMMh5E38VisPxSN7BGxBVXHtn0cUPmZLmYSzGrOJqEJzimvwh2uDi8uXEOwBLbsfYlxBOz1kw8Pk

255 , - 256. , .

for i in {0..4096}; do ln -s $i $(expr $i + 1); done
+4

All Articles